@remnic/core 9.3.704 → 9.3.705
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 +1 -1
- package/dist/access-boundary.js +25 -25
- package/dist/access-cli.js +53 -52
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.js +30 -29
- package/dist/access-mcp.js +29 -28
- package/dist/access-operations-batch.d.ts +2 -0
- package/dist/access-operations-batch.js +120 -0
- package/dist/access-operations.d.ts +1 -0
- package/dist/access-operations.js +28 -27
- package/dist/access-schema.js +3 -3
- package/dist/access-service.js +24 -24
- package/dist/access-surface-catalog.js +57 -54
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/{auto-sync-3AAP25FV.js → auto-sync-24NNS3GU.js} +3 -3
- package/dist/briefing.js +4 -4
- package/dist/{capsule-crypto-GWVG7LGC.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 +8 -8
- package/dist/causal-retrieval.js +3 -3
- package/dist/causal-trajectory-graph.js +2 -2
- package/dist/causal-trajectory.js +1 -1
- package/dist/{chunk-OWHERGF2.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-PJ5MDXOF.js → chunk-2SYPOX45.js} +10 -10
- package/dist/{chunk-7G4KPGR3.js → chunk-47LPHBIP.js} +2 -2
- package/dist/{chunk-RYDT7LAI.js → chunk-5DTWZ66X.js} +2 -2
- package/dist/chunk-5DTWZ66X.js.map +1 -0
- package/dist/{chunk-OCFNG4LB.js → chunk-6GJ2WQRK.js} +2 -2
- package/dist/{chunk-4NFVPDIL.js → chunk-74MYJSKB.js} +5 -5
- package/dist/{chunk-PKMQK2WY.js → chunk-773DPI6T.js} +4 -4
- package/dist/{chunk-DE2OPIQD.js → chunk-7ARKLLCV.js} +6 -6
- package/dist/{chunk-3EHCV6YV.js → chunk-7L54YZUI.js} +63 -63
- package/dist/{chunk-AGNBY3VG.js → chunk-APJQ6UEA.js} +4 -4
- package/dist/{chunk-UNNDFYUX.js → chunk-ARV3AUOM.js} +5 -5
- package/dist/{chunk-S24J5LLQ.js → chunk-BKBSE3BU.js} +3 -3
- package/dist/{chunk-AE3C4PY6.js → chunk-BMKGG7GC.js} +2 -2
- package/dist/{chunk-NMW3T6T6.js → chunk-C2EHWNP2.js} +9 -9
- package/dist/{chunk-VKJHM6PL.js → chunk-DGTDRIUO.js} +5 -5
- package/dist/chunk-GI3MTYDU.js +1303 -0
- package/dist/chunk-GI3MTYDU.js.map +1 -0
- package/dist/{chunk-25FHSOEB.js → chunk-GT4VBKM4.js} +59 -5
- package/dist/chunk-GT4VBKM4.js.map +1 -0
- package/dist/{chunk-OOEVMJK4.js → chunk-HEHPVBWA.js} +6 -6
- package/dist/{chunk-YOI3ELXF.js → chunk-IF362TF6.js} +2 -2
- package/dist/{chunk-ABCGDW3A.js → chunk-IFR23TC5.js} +4 -4
- package/dist/{chunk-ZXFNSKPY.js → chunk-JHAYR2JY.js} +32 -32
- package/dist/{chunk-CTY6QSLZ.js → chunk-JZCKDTAS.js} +4 -4
- package/dist/{chunk-CTY6QSLZ.js.map → chunk-JZCKDTAS.js.map} +1 -1
- package/dist/{chunk-6AFVIOVZ.js → chunk-K22IJO4R.js} +2 -2
- package/dist/{chunk-QV5WFNZ2.js → chunk-KFU2SKDD.js} +2 -2
- package/dist/{chunk-5W7CTZ2E.js → chunk-KQAFEZQX.js} +4 -4
- package/dist/{chunk-TUPNAHHQ.js → chunk-KZMMAVR2.js} +2 -2
- package/dist/{chunk-6Q7JFY4P.js → chunk-LY4FJLPT.js} +2 -2
- package/dist/{chunk-XXDOJ5NL.js → chunk-M5MWSG4S.js} +7 -7
- package/dist/{chunk-YLB7NMLD.js → chunk-MNH2OODZ.js} +2 -2
- package/dist/{chunk-ORXVO6TH.js → chunk-NFGJBEPT.js} +6 -6
- package/dist/{chunk-QDIVMS25.js → chunk-NUWZFSKC.js} +2 -2
- package/dist/{chunk-6GHWF4QH.js → chunk-OM6ETLLH.js} +2 -2
- package/dist/{chunk-53EEQYE5.js → chunk-OMSTU233.js} +4 -4
- package/dist/{chunk-R64MNFPV.js → chunk-S3WYRPSA.js} +59 -59
- package/dist/{chunk-UOIRJ45Z.js → chunk-S5APSA3U.js} +2 -2
- package/dist/{chunk-WAHI7SPK.js → chunk-SY6WG6DB.js} +2 -2
- package/dist/{chunk-K7QRDDSR.js → chunk-ULVM34NP.js} +5 -5
- package/dist/{chunk-UVYI6VIX.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-QHNJVWF6.js → chunk-Y4PMATX2.js} +6 -6
- package/dist/{chunk-KF74X62T.js → chunk-YGKUAX2B.js} +4 -4
- package/dist/{chunk-YN4ZT4CW.js → chunk-YI7RZO7Y.js} +1 -1
- package/dist/cli.js +53 -52
- package/dist/compounding/engine.js +4 -4
- package/dist/connectors/codex-materialize-runner.js +4 -4
- package/dist/connectors/index.js +4 -4
- package/dist/entity-retrieval.js +4 -4
- package/dist/extraction.js +2 -2
- package/dist/{graph-edge-decay-D7OESCBR.js → graph-edge-decay-JLOF3YW4.js} +3 -3
- package/dist/graph-snapshot.js +3 -3
- package/dist/graph.js +2 -2
- package/dist/index.js +95 -94
- package/dist/index.js.map +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.js +4 -4
- package/dist/maintenance/memory-governance.js +5 -5
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +4 -4
- package/dist/maintenance/rebuild-memory-projection.js +6 -6
- package/dist/namespaces/migrate.js +8 -8
- package/dist/namespaces/search.js +3 -3
- package/dist/namespaces/storage.js +4 -4
- package/dist/operator-toolkit.js +15 -15
- package/dist/orchestration/maintenance.js +6 -6
- package/dist/orchestrator.js +40 -40
- package/dist/resume-bundles.js +1 -1
- package/dist/search/factory.js +2 -2
- package/dist/search/index.js +4 -4
- package/dist/semantic-consolidation.js +6 -6
- package/dist/semantic-rule-promotion.js +4 -4
- package/dist/semantic-rule-verifier.js +5 -5
- package/dist/storage.js +3 -3
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/import-sqlite.js +2 -2
- package/dist/verified-recall.js +5 -5
- package/package.json +2 -2
- package/src/access-boundary.ts +102 -1
- package/src/access-http.ts +54 -0
- package/src/access-operations-batch.ts +1468 -0
- package/src/access-operations.ts +4 -0
- package/src/access-surface-catalog.test.ts +17 -1
- package/src/access-surface-catalog.ts +57 -54
- package/src/storage-contract/atomicity.test.ts +113 -0
- package/src/storage-contract/cache-coherence.test.ts +100 -0
- package/src/storage-contract/content-hash.test.ts +102 -0
- package/src/storage-contract/failure-semantics.test.ts +108 -0
- package/src/storage-contract/harness.ts +148 -0
- package/src/storage-contract/namespace-routing.test.ts +135 -0
- package/src/storage-contract/round-trip.test.ts +226 -0
- package/src/storage-contract/surface.test.ts +90 -0
- package/src/storage-contract/versioning.test.ts +139 -0
- package/dist/chunk-25FHSOEB.js.map +0 -1
- package/dist/chunk-RYDT7LAI.js.map +0 -1
- /package/dist/{capsule-crypto-GWVG7LGC.js.map → access-operations-batch.js.map} +0 -0
- /package/dist/{auto-sync-3AAP25FV.js.map → auto-sync-24NNS3GU.js.map} +0 -0
- /package/dist/{chunk-OWHERGF2.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-PJ5MDXOF.js.map → chunk-2SYPOX45.js.map} +0 -0
- /package/dist/{chunk-7G4KPGR3.js.map → chunk-47LPHBIP.js.map} +0 -0
- /package/dist/{chunk-OCFNG4LB.js.map → chunk-6GJ2WQRK.js.map} +0 -0
- /package/dist/{chunk-4NFVPDIL.js.map → chunk-74MYJSKB.js.map} +0 -0
- /package/dist/{chunk-PKMQK2WY.js.map → chunk-773DPI6T.js.map} +0 -0
- /package/dist/{chunk-DE2OPIQD.js.map → chunk-7ARKLLCV.js.map} +0 -0
- /package/dist/{chunk-3EHCV6YV.js.map → chunk-7L54YZUI.js.map} +0 -0
- /package/dist/{chunk-AGNBY3VG.js.map → chunk-APJQ6UEA.js.map} +0 -0
- /package/dist/{chunk-UNNDFYUX.js.map → chunk-ARV3AUOM.js.map} +0 -0
- /package/dist/{chunk-S24J5LLQ.js.map → chunk-BKBSE3BU.js.map} +0 -0
- /package/dist/{chunk-AE3C4PY6.js.map → chunk-BMKGG7GC.js.map} +0 -0
- /package/dist/{chunk-NMW3T6T6.js.map → chunk-C2EHWNP2.js.map} +0 -0
- /package/dist/{chunk-VKJHM6PL.js.map → chunk-DGTDRIUO.js.map} +0 -0
- /package/dist/{chunk-OOEVMJK4.js.map → chunk-HEHPVBWA.js.map} +0 -0
- /package/dist/{chunk-YOI3ELXF.js.map → chunk-IF362TF6.js.map} +0 -0
- /package/dist/{chunk-ABCGDW3A.js.map → chunk-IFR23TC5.js.map} +0 -0
- /package/dist/{chunk-ZXFNSKPY.js.map → chunk-JHAYR2JY.js.map} +0 -0
- /package/dist/{chunk-6AFVIOVZ.js.map → chunk-K22IJO4R.js.map} +0 -0
- /package/dist/{chunk-QV5WFNZ2.js.map → chunk-KFU2SKDD.js.map} +0 -0
- /package/dist/{chunk-5W7CTZ2E.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-TUPNAHHQ.js.map → chunk-KZMMAVR2.js.map} +0 -0
- /package/dist/{chunk-6Q7JFY4P.js.map → chunk-LY4FJLPT.js.map} +0 -0
- /package/dist/{chunk-XXDOJ5NL.js.map → chunk-M5MWSG4S.js.map} +0 -0
- /package/dist/{chunk-YLB7NMLD.js.map → chunk-MNH2OODZ.js.map} +0 -0
- /package/dist/{chunk-ORXVO6TH.js.map → chunk-NFGJBEPT.js.map} +0 -0
- /package/dist/{chunk-QDIVMS25.js.map → chunk-NUWZFSKC.js.map} +0 -0
- /package/dist/{chunk-6GHWF4QH.js.map → chunk-OM6ETLLH.js.map} +0 -0
- /package/dist/{chunk-53EEQYE5.js.map → chunk-OMSTU233.js.map} +0 -0
- /package/dist/{chunk-R64MNFPV.js.map → chunk-S3WYRPSA.js.map} +0 -0
- /package/dist/{chunk-UOIRJ45Z.js.map → chunk-S5APSA3U.js.map} +0 -0
- /package/dist/{chunk-WAHI7SPK.js.map → chunk-SY6WG6DB.js.map} +0 -0
- /package/dist/{chunk-K7QRDDSR.js.map → chunk-ULVM34NP.js.map} +0 -0
- /package/dist/{chunk-UVYI6VIX.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-QHNJVWF6.js.map → chunk-Y4PMATX2.js.map} +0 -0
- /package/dist/{chunk-KF74X62T.js.map → chunk-YGKUAX2B.js.map} +0 -0
- /package/dist/{chunk-YN4ZT4CW.js.map → chunk-YI7RZO7Y.js.map} +0 -0
- /package/dist/{graph-edge-decay-D7OESCBR.js.map → graph-edge-decay-JLOF3YW4.js.map} +0 -0
|
@@ -0,0 +1,1468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Batch migration of remaining access-surface handlers through the boundary
|
|
3
|
+
* (issue #1525). Each operation routes MCP/HTTP/CLI dispatch through the
|
|
4
|
+
* shared validation + error-mapping layer in access-boundary.ts.
|
|
5
|
+
*
|
|
6
|
+
* Schemas use a null-stripping preprocessor (MCP clients send null for absent
|
|
7
|
+
* optional fields — repo gotcha #2) over a permissive record. Individual
|
|
8
|
+
* schema tightening lands as follow-up PRs; the boundary already centralizes
|
|
9
|
+
* error mapping and enforces "no handler bypasses the boundary."
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
import { defineOperation, type OperationContext } from "./access-boundary.js";
|
|
14
|
+
import { EngramAccessInputError, type EngramAccessService } from "./access-service.js";
|
|
15
|
+
import type { RecallPlanMode, RecallDisclosure } from "./types.js";
|
|
16
|
+
import { projectTagProjectId } from "./coding/coding-namespace.js";
|
|
17
|
+
import { expandTildePath } from "./utils/path.js";
|
|
18
|
+
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// Shared helpers — type-safe extraction from unknown input (no `any`)
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
/** Strip null values from an object (MCP clients send null for absent optionals). */
|
|
24
|
+
function stripNulls(data: unknown): unknown {
|
|
25
|
+
if (data !== null && typeof data === "object" && !Array.isArray(data)) {
|
|
26
|
+
const obj = data as Record<string, unknown>;
|
|
27
|
+
const cleaned: Record<string, unknown> = {};
|
|
28
|
+
for (const [key, value] of Object.entries(obj)) {
|
|
29
|
+
if (value !== null) cleaned[key] = value;
|
|
30
|
+
}
|
|
31
|
+
return cleaned;
|
|
32
|
+
}
|
|
33
|
+
return data;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** Permissive schema: null-strip then accept any string-keyed record. */
|
|
37
|
+
const looseSchema = z.preprocess(
|
|
38
|
+
stripNulls,
|
|
39
|
+
z.record(z.string(), z.unknown()),
|
|
40
|
+
) as z.ZodType<Record<string, unknown>>;
|
|
41
|
+
|
|
42
|
+
function optStr(v: unknown): string | undefined {
|
|
43
|
+
return typeof v === "string" ? v : undefined;
|
|
44
|
+
}
|
|
45
|
+
function reqStr(v: unknown, field: string): string {
|
|
46
|
+
if (typeof v !== "string" || v.length === 0) {
|
|
47
|
+
throw new EngramAccessInputError(`${field} is required and must be a non-empty string`);
|
|
48
|
+
}
|
|
49
|
+
return v;
|
|
50
|
+
}
|
|
51
|
+
function defStr(v: unknown, d: string): string {
|
|
52
|
+
return typeof v === "string" ? v : d;
|
|
53
|
+
}
|
|
54
|
+
function optNum(v: unknown): number | undefined {
|
|
55
|
+
return typeof v === "number" && Number.isFinite(v) ? v : undefined;
|
|
56
|
+
}
|
|
57
|
+
function optBool(v: unknown): boolean | undefined {
|
|
58
|
+
return typeof v === "boolean" ? v : undefined;
|
|
59
|
+
}
|
|
60
|
+
function optStrArr(v: unknown): string[] | undefined {
|
|
61
|
+
return Array.isArray(v) && v.every((x) => typeof x === "string") ? v : undefined;
|
|
62
|
+
}
|
|
63
|
+
// ===========================================================================
|
|
64
|
+
// Recall operations
|
|
65
|
+
// ===========================================================================
|
|
66
|
+
|
|
67
|
+
defineOperation({
|
|
68
|
+
name: "recall",
|
|
69
|
+
description: "Semantic recall across memories.",
|
|
70
|
+
schema: looseSchema,
|
|
71
|
+
handler: async (input, ctx) => {
|
|
72
|
+
const result = await ctx.service.recall({
|
|
73
|
+
query: defStr(input.query, ""),
|
|
74
|
+
sessionKey: optStr(input.sessionKey),
|
|
75
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
76
|
+
namespace: optStr(input.namespace),
|
|
77
|
+
topK: optNum(input.topK),
|
|
78
|
+
mode: optStr(input.mode) as RecallPlanMode | "auto" | undefined,
|
|
79
|
+
includeDebug: input.includeDebug === true,
|
|
80
|
+
disclosure: optStr(input.disclosure) as RecallDisclosure | undefined,
|
|
81
|
+
cwd: optStr(input.cwd),
|
|
82
|
+
projectTag: optStr(input.projectTag),
|
|
83
|
+
asOf: optStr(input.asOf),
|
|
84
|
+
...(optStrArr(input.tags) !== undefined ? { tags: optStrArr(input.tags)! } : {}),
|
|
85
|
+
...(optStr(input.tagMatch) !== undefined ? { tagMatch: optStr(input.tagMatch) as "any" | "all" } : {}),
|
|
86
|
+
});
|
|
87
|
+
return { result };
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
defineOperation({
|
|
92
|
+
name: "recall_explain",
|
|
93
|
+
description: "Explain the recall plan for the session.",
|
|
94
|
+
schema: looseSchema,
|
|
95
|
+
handler: async (input, ctx) => {
|
|
96
|
+
const result = await ctx.service.recallExplain({
|
|
97
|
+
sessionKey: optStr(input.sessionKey),
|
|
98
|
+
namespace: optStr(input.namespace),
|
|
99
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
100
|
+
});
|
|
101
|
+
return { result };
|
|
102
|
+
},
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
defineOperation({
|
|
106
|
+
name: "set_coding_context",
|
|
107
|
+
description: "Set the coding context for a session (issue #569).",
|
|
108
|
+
schema: looseSchema,
|
|
109
|
+
handler: async (input, ctx) => {
|
|
110
|
+
const sessionKey = defStr(input.sessionKey, "");
|
|
111
|
+
const projectTag = optStr(input.projectTag);
|
|
112
|
+
const hasProjectTag = projectTag !== undefined && projectTag.trim().length > 0;
|
|
113
|
+
const hasCodingContext = "codingContext" in input;
|
|
114
|
+
if (!hasCodingContext && hasProjectTag) {
|
|
115
|
+
const tag = projectTag!.trim();
|
|
116
|
+
const projectId = projectTagProjectId(tag);
|
|
117
|
+
ctx.service.setCodingContext({
|
|
118
|
+
sessionKey,
|
|
119
|
+
codingContext: { projectId, branch: null, rootPath: projectId, defaultBranch: null },
|
|
120
|
+
});
|
|
121
|
+
return { result: { ok: true } };
|
|
122
|
+
}
|
|
123
|
+
if (!hasCodingContext && !hasProjectTag) {
|
|
124
|
+
throw new EngramAccessInputError("set_coding_context requires either codingContext or projectTag");
|
|
125
|
+
}
|
|
126
|
+
const rawCtx = input.codingContext;
|
|
127
|
+
let codingContext: { projectId: string; branch: string | null; rootPath: string; defaultBranch: string | null } | null = null;
|
|
128
|
+
if (rawCtx !== null) {
|
|
129
|
+
if (typeof rawCtx !== "object" || rawCtx === undefined) {
|
|
130
|
+
throw new EngramAccessInputError("codingContext must be an object or null");
|
|
131
|
+
}
|
|
132
|
+
const obj = rawCtx as Record<string, unknown>;
|
|
133
|
+
const projectId = defStr(obj.projectId, "");
|
|
134
|
+
const rootPath = defStr(obj.rootPath, "");
|
|
135
|
+
const branch = obj.branch === null ? null : optStr(obj.branch);
|
|
136
|
+
const defaultBranch = obj.defaultBranch === null ? null : optStr(obj.defaultBranch);
|
|
137
|
+
if (branch === undefined) throw new EngramAccessInputError("codingContext.branch must be a string or null");
|
|
138
|
+
if (defaultBranch === undefined) throw new EngramAccessInputError("codingContext.defaultBranch must be a string or null");
|
|
139
|
+
codingContext = { projectId, branch, rootPath, defaultBranch };
|
|
140
|
+
}
|
|
141
|
+
ctx.service.setCodingContext({ sessionKey, codingContext });
|
|
142
|
+
return { result: { ok: true } };
|
|
143
|
+
},
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
defineOperation({
|
|
147
|
+
name: "recall_tier_explain",
|
|
148
|
+
description: "Explain the recall tier breakdown.",
|
|
149
|
+
schema: looseSchema,
|
|
150
|
+
handler: async (input, ctx) => {
|
|
151
|
+
const sessionKey = optStr(input.sessionKey);
|
|
152
|
+
const namespace = optStr(input.namespace);
|
|
153
|
+
const result = await ctx.service.recallTierExplain(
|
|
154
|
+
sessionKey !== undefined && sessionKey.length > 0 ? sessionKey : undefined,
|
|
155
|
+
namespace !== undefined && namespace.length > 0 ? namespace : undefined,
|
|
156
|
+
ctx.authenticatedPrincipal,
|
|
157
|
+
);
|
|
158
|
+
return { result };
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
defineOperation({
|
|
163
|
+
name: "recall_xray",
|
|
164
|
+
description: "X-ray the recall pipeline for a query.",
|
|
165
|
+
schema: looseSchema,
|
|
166
|
+
handler: async (input, ctx) => {
|
|
167
|
+
const budgetRaw = input.budget;
|
|
168
|
+
let budget: number | undefined;
|
|
169
|
+
if (budgetRaw !== undefined && budgetRaw !== null) {
|
|
170
|
+
const parsed = typeof budgetRaw === "number" ? budgetRaw : typeof budgetRaw === "string" ? Number(budgetRaw) : undefined;
|
|
171
|
+
if (parsed === undefined || !Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
|
|
172
|
+
throw new EngramAccessInputError("recall_xray: budget expects a positive integer");
|
|
173
|
+
}
|
|
174
|
+
budget = parsed;
|
|
175
|
+
}
|
|
176
|
+
const disclosureRaw = optStr(input.disclosure);
|
|
177
|
+
const result = await ctx.service.recallXray({
|
|
178
|
+
query: defStr(input.query, ""),
|
|
179
|
+
sessionKey: optStr(input.sessionKey),
|
|
180
|
+
namespace: optStr(input.namespace),
|
|
181
|
+
budget,
|
|
182
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
183
|
+
...(disclosureRaw !== undefined && disclosureRaw !== "" ? { disclosure: disclosureRaw as RecallDisclosure } : {}),
|
|
184
|
+
});
|
|
185
|
+
return { result };
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
// ===========================================================================
|
|
190
|
+
// Wearables + transcript operations
|
|
191
|
+
// ===========================================================================
|
|
192
|
+
|
|
193
|
+
defineOperation({
|
|
194
|
+
name: "wearables_status",
|
|
195
|
+
description: "Get wearables sync status.",
|
|
196
|
+
schema: looseSchema,
|
|
197
|
+
handler: async (_input, ctx) => ({ result: await ctx.service.wearablesStatus() }),
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
defineOperation({
|
|
201
|
+
name: "wearables_sync",
|
|
202
|
+
description: "Sync wearables data.",
|
|
203
|
+
schema: looseSchema,
|
|
204
|
+
handler: async (input, ctx) => {
|
|
205
|
+
const result = await ctx.service.wearablesSync({
|
|
206
|
+
source: optStr(input.source),
|
|
207
|
+
date: optStr(input.date),
|
|
208
|
+
days: optNum(input.days),
|
|
209
|
+
forceMemories: optBool(input.forceMemories),
|
|
210
|
+
});
|
|
211
|
+
return { result };
|
|
212
|
+
},
|
|
213
|
+
});
|
|
214
|
+
|
|
215
|
+
defineOperation({
|
|
216
|
+
name: "transcript_day",
|
|
217
|
+
description: "Get transcript for a specific day.",
|
|
218
|
+
schema: looseSchema,
|
|
219
|
+
handler: async (input, ctx) => {
|
|
220
|
+
const date = defStr(input.date, "");
|
|
221
|
+
if (date.trim().length === 0) throw new EngramAccessInputError("transcript_day: date is required and must be YYYY-MM-DD");
|
|
222
|
+
const result = await ctx.service.wearablesTranscriptDay({ date, source: optStr(input.source) });
|
|
223
|
+
return { result };
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
defineOperation({
|
|
228
|
+
name: "transcript_search",
|
|
229
|
+
description: "Search transcripts.",
|
|
230
|
+
schema: looseSchema,
|
|
231
|
+
handler: async (input, ctx) => {
|
|
232
|
+
const query = defStr(input.query, "");
|
|
233
|
+
if (query.trim().length === 0) throw new EngramAccessInputError("transcript_search: query is required and must be non-empty");
|
|
234
|
+
const result = await ctx.service.wearablesTranscriptSearch({
|
|
235
|
+
query,
|
|
236
|
+
source: optStr(input.source),
|
|
237
|
+
from: optStr(input.from),
|
|
238
|
+
to: optStr(input.to),
|
|
239
|
+
limit: optNum(input.limit),
|
|
240
|
+
});
|
|
241
|
+
return { result };
|
|
242
|
+
},
|
|
243
|
+
});
|
|
244
|
+
|
|
245
|
+
defineOperation({
|
|
246
|
+
name: "transcript_memories",
|
|
247
|
+
description: "Get transcript memories.",
|
|
248
|
+
schema: looseSchema,
|
|
249
|
+
handler: async (input, ctx) => {
|
|
250
|
+
const result = await ctx.service.wearablesTranscriptMemories({
|
|
251
|
+
source: optStr(input.source),
|
|
252
|
+
date: optStr(input.date),
|
|
253
|
+
limit: optNum(input.limit),
|
|
254
|
+
});
|
|
255
|
+
return { result };
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// ===========================================================================
|
|
260
|
+
// Action confidence, day summary, capsule operations
|
|
261
|
+
// ===========================================================================
|
|
262
|
+
|
|
263
|
+
defineOperation({
|
|
264
|
+
name: "action_confidence",
|
|
265
|
+
description: "Get action confidence for recent memories.",
|
|
266
|
+
schema: looseSchema,
|
|
267
|
+
handler: async (input, ctx) => {
|
|
268
|
+
const result = await ctx.service.actionConfidence({
|
|
269
|
+
intendedAction: optStr(input.intendedAction),
|
|
270
|
+
confidence: optNum(input.confidence),
|
|
271
|
+
risk: optStr(input.risk) as import("./action-confidence.js").ActionConfidenceRiskCategory | undefined,
|
|
272
|
+
contextReadiness: optStr(input.contextReadiness) as import("./action-confidence.js").ActionConfidenceContextReadiness | undefined,
|
|
273
|
+
currentContextScopes: optStrArr(input.currentContextScopes),
|
|
274
|
+
});
|
|
275
|
+
return { result };
|
|
276
|
+
},
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
defineOperation({
|
|
280
|
+
name: "chatgpt_memory_inspector",
|
|
281
|
+
description: "ChatGPT memory inspector (recall xray + action confidence orchestrator).",
|
|
282
|
+
schema: looseSchema,
|
|
283
|
+
handler: async (input, ctx) => {
|
|
284
|
+
const xray = await ctx.service.recallXray({
|
|
285
|
+
query: defStr(input.query, ""),
|
|
286
|
+
sessionKey: optStr(input.sessionKey),
|
|
287
|
+
namespace: optStr(input.namespace),
|
|
288
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
289
|
+
});
|
|
290
|
+
const confidence = await ctx.service.actionConfidence({});
|
|
291
|
+
return { result: { xray, confidence } };
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
defineOperation({
|
|
296
|
+
name: "day_summary",
|
|
297
|
+
description: "Get a day summary.",
|
|
298
|
+
schema: looseSchema,
|
|
299
|
+
handler: async (input, ctx) => {
|
|
300
|
+
const result = await ctx.service.daySummary({
|
|
301
|
+
memories: optStr(input.memories),
|
|
302
|
+
sessionKey: optStr(input.sessionKey),
|
|
303
|
+
namespace: optStr(input.namespace),
|
|
304
|
+
timeZone: optStr(input.timeZone),
|
|
305
|
+
});
|
|
306
|
+
return { result };
|
|
307
|
+
},
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
defineOperation({
|
|
311
|
+
name: "capsule_export",
|
|
312
|
+
description: "Export a capsule.",
|
|
313
|
+
schema: looseSchema,
|
|
314
|
+
handler: async (input, ctx) => {
|
|
315
|
+
const result = await ctx.service.capsuleExport({
|
|
316
|
+
name: optStr(input.name) ?? "",
|
|
317
|
+
namespace: optStr(input.namespace),
|
|
318
|
+
since: optStr(input.since),
|
|
319
|
+
includeKinds: optStrArr(input.includeKinds),
|
|
320
|
+
peerIds: optStrArr(input.peerIds),
|
|
321
|
+
includeTranscripts: optBool(input.includeTranscripts),
|
|
322
|
+
encrypt: optBool(input.encrypt),
|
|
323
|
+
principal: ctx.authenticatedPrincipal,
|
|
324
|
+
} as Parameters<typeof ctx.service.capsuleExport>[0]);
|
|
325
|
+
return { result };
|
|
326
|
+
},
|
|
327
|
+
});
|
|
328
|
+
|
|
329
|
+
defineOperation({
|
|
330
|
+
name: "capsule_import",
|
|
331
|
+
description: "Import a capsule.",
|
|
332
|
+
schema: looseSchema,
|
|
333
|
+
handler: async (input, ctx) => {
|
|
334
|
+
const result = await ctx.service.capsuleImport({
|
|
335
|
+
archivePath: expandTildePath(optStr(input.archivePath) ?? ""),
|
|
336
|
+
namespace: optStr(input.namespace),
|
|
337
|
+
mode: optStr(input.mode) as "skip" | "overwrite" | "fork" | undefined,
|
|
338
|
+
passphrase: optStr(input.passphrase),
|
|
339
|
+
principal: ctx.authenticatedPrincipal,
|
|
340
|
+
});
|
|
341
|
+
return { result };
|
|
342
|
+
},
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
defineOperation({
|
|
346
|
+
name: "capsule_list",
|
|
347
|
+
description: "List capsules.",
|
|
348
|
+
schema: looseSchema,
|
|
349
|
+
handler: async (input, ctx) => {
|
|
350
|
+
const result = await ctx.service.capsuleList({
|
|
351
|
+
namespace: optStr(input.namespace),
|
|
352
|
+
principal: ctx.authenticatedPrincipal,
|
|
353
|
+
});
|
|
354
|
+
return { result };
|
|
355
|
+
},
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
// ===========================================================================
|
|
359
|
+
// Governance, maintenance, procedural operations
|
|
360
|
+
// ===========================================================================
|
|
361
|
+
|
|
362
|
+
defineOperation({
|
|
363
|
+
name: "memory_governance_run",
|
|
364
|
+
description: "Run memory governance.",
|
|
365
|
+
schema: looseSchema,
|
|
366
|
+
handler: async (input, ctx) => {
|
|
367
|
+
const result = await ctx.service.governanceRun({
|
|
368
|
+
namespace: optStr(input.namespace),
|
|
369
|
+
mode: optStr(input.mode) as "shadow" | "apply" | undefined,
|
|
370
|
+
recentDays: optNum(input.recentDays),
|
|
371
|
+
maxMemories: optNum(input.maxMemories),
|
|
372
|
+
batchSize: optNum(input.batchSize),
|
|
373
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
374
|
+
});
|
|
375
|
+
return { result };
|
|
376
|
+
},
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
defineOperation({
|
|
380
|
+
name: "procedure_mining_run",
|
|
381
|
+
description: "Run procedure mining.",
|
|
382
|
+
schema: looseSchema,
|
|
383
|
+
handler: async (input, ctx) => {
|
|
384
|
+
const result = await ctx.service.procedureMiningRun({
|
|
385
|
+
namespace: optStr(input.namespace),
|
|
386
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
387
|
+
});
|
|
388
|
+
return { result };
|
|
389
|
+
},
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
defineOperation({
|
|
393
|
+
name: "pattern_reinforcement_run",
|
|
394
|
+
description: "Run pattern reinforcement.",
|
|
395
|
+
schema: looseSchema,
|
|
396
|
+
handler: async (input, ctx) => {
|
|
397
|
+
const result = await ctx.service.patternReinforcementRun({
|
|
398
|
+
namespace: optStr(input.namespace),
|
|
399
|
+
force: input.force === true,
|
|
400
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
401
|
+
});
|
|
402
|
+
return { result };
|
|
403
|
+
},
|
|
404
|
+
});
|
|
405
|
+
|
|
406
|
+
defineOperation({
|
|
407
|
+
name: "procedural_stats",
|
|
408
|
+
description: "Get procedural stats.",
|
|
409
|
+
schema: looseSchema,
|
|
410
|
+
handler: async (input, ctx) => {
|
|
411
|
+
const result = await ctx.service.procedureStats({ namespace: optStr(input.namespace) }, ctx.authenticatedPrincipal);
|
|
412
|
+
return { result };
|
|
413
|
+
},
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
// ===========================================================================
|
|
417
|
+
// Memory timeline, suggestion, entity, observe, LCM operations
|
|
418
|
+
// ===========================================================================
|
|
419
|
+
|
|
420
|
+
defineOperation({
|
|
421
|
+
name: "memory_timeline",
|
|
422
|
+
description: "Get the timeline for a memory.",
|
|
423
|
+
schema: looseSchema,
|
|
424
|
+
handler: async (input, ctx) => {
|
|
425
|
+
const result = await ctx.service.memoryTimeline(
|
|
426
|
+
optStr(input.memoryId) ?? "",
|
|
427
|
+
optStr(input.namespace),
|
|
428
|
+
optNum(input.limit),
|
|
429
|
+
ctx.authenticatedPrincipal,
|
|
430
|
+
);
|
|
431
|
+
return { result };
|
|
432
|
+
},
|
|
433
|
+
});
|
|
434
|
+
|
|
435
|
+
defineOperation({
|
|
436
|
+
name: "suggestion_submit",
|
|
437
|
+
description: "Submit a memory suggestion.",
|
|
438
|
+
schema: looseSchema,
|
|
439
|
+
handler: async (input, ctx) => {
|
|
440
|
+
const result = await ctx.service.suggestionSubmit({
|
|
441
|
+
schemaVersion: optNum(input.schemaVersion),
|
|
442
|
+
idempotencyKey: optStr(input.idempotencyKey),
|
|
443
|
+
dryRun: input.dryRun === true,
|
|
444
|
+
sessionKey: optStr(input.sessionKey),
|
|
445
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
446
|
+
content: optStr(input.content) ?? "",
|
|
447
|
+
category: optStr(input.category),
|
|
448
|
+
confidence: optNum(input.confidence),
|
|
449
|
+
namespace: optStr(input.namespace),
|
|
450
|
+
tags: optStrArr(input.tags),
|
|
451
|
+
entityRef: optStr(input.entityRef),
|
|
452
|
+
ttl: optStr(input.ttl),
|
|
453
|
+
sourceReason: optStr(input.sourceReason),
|
|
454
|
+
cwd: optStr(input.cwd),
|
|
455
|
+
projectTag: optStr(input.projectTag),
|
|
456
|
+
});
|
|
457
|
+
return { result };
|
|
458
|
+
},
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
defineOperation({
|
|
462
|
+
name: "entity_get",
|
|
463
|
+
description: "Get an entity by name.",
|
|
464
|
+
schema: looseSchema,
|
|
465
|
+
handler: async (input, ctx) => {
|
|
466
|
+
const result = await ctx.service.entityGet(optStr(input.name) ?? "", optStr(input.namespace));
|
|
467
|
+
return { result };
|
|
468
|
+
},
|
|
469
|
+
});
|
|
470
|
+
|
|
471
|
+
defineOperation({
|
|
472
|
+
name: "review_queue_list",
|
|
473
|
+
description: "List the review queue.",
|
|
474
|
+
schema: looseSchema,
|
|
475
|
+
handler: async (input, ctx) => {
|
|
476
|
+
const result = await ctx.service.reviewQueue(optStr(input.runId) ?? "", optStr(input.namespace), ctx.authenticatedPrincipal);
|
|
477
|
+
return { result };
|
|
478
|
+
},
|
|
479
|
+
});
|
|
480
|
+
|
|
481
|
+
defineOperation({
|
|
482
|
+
name: "observe",
|
|
483
|
+
description: "Observe messages into the memory system.",
|
|
484
|
+
schema: looseSchema,
|
|
485
|
+
handler: async (input, ctx) => {
|
|
486
|
+
const messages = input.messages;
|
|
487
|
+
if (!Array.isArray(messages)) throw new EngramAccessInputError("observe: messages must be an array");
|
|
488
|
+
const result = await ctx.service.observe({
|
|
489
|
+
sessionKey: defStr(input.sessionKey, ""),
|
|
490
|
+
messages: messages as unknown as Parameters<typeof ctx.service.observe>[0]["messages"],
|
|
491
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
492
|
+
namespace: optStr(input.namespace),
|
|
493
|
+
skipExtraction: input.skipExtraction === true,
|
|
494
|
+
cwd: optStr(input.cwd),
|
|
495
|
+
projectTag: optStr(input.projectTag),
|
|
496
|
+
});
|
|
497
|
+
return { result };
|
|
498
|
+
},
|
|
499
|
+
});
|
|
500
|
+
|
|
501
|
+
defineOperation({
|
|
502
|
+
name: "lcm_search",
|
|
503
|
+
description: "Search the LCM (long-context memory).",
|
|
504
|
+
schema: looseSchema,
|
|
505
|
+
handler: async (input, ctx) => {
|
|
506
|
+
const result = await ctx.service.lcmSearch({
|
|
507
|
+
query: defStr(input.query, ""),
|
|
508
|
+
sessionKey: optStr(input.sessionKey),
|
|
509
|
+
sessionPrefix: optStr(input.sessionPrefix),
|
|
510
|
+
namespace: optStr(input.namespace),
|
|
511
|
+
limit: optNum(input.limit),
|
|
512
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
513
|
+
});
|
|
514
|
+
return { result };
|
|
515
|
+
},
|
|
516
|
+
});
|
|
517
|
+
|
|
518
|
+
defineOperation({
|
|
519
|
+
name: "lcm_compaction_flush",
|
|
520
|
+
description: "Flush LCM compaction.",
|
|
521
|
+
schema: looseSchema,
|
|
522
|
+
handler: async (input, ctx) => {
|
|
523
|
+
const result = await ctx.service.lcmCompactionFlush({
|
|
524
|
+
sessionKey: optStr(input.sessionKey) ?? "",
|
|
525
|
+
namespace: optStr(input.namespace),
|
|
526
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
527
|
+
});
|
|
528
|
+
return { result };
|
|
529
|
+
},
|
|
530
|
+
});
|
|
531
|
+
|
|
532
|
+
defineOperation({
|
|
533
|
+
name: "lcm_compaction_record",
|
|
534
|
+
description: "Record an LCM compaction.",
|
|
535
|
+
schema: looseSchema,
|
|
536
|
+
handler: async (input, ctx) => {
|
|
537
|
+
const result = await ctx.service.lcmCompactionRecord({
|
|
538
|
+
sessionKey: optStr(input.sessionKey) ?? "",
|
|
539
|
+
namespace: optStr(input.namespace),
|
|
540
|
+
tokensBefore: optNum(input.tokensBefore) ?? 0,
|
|
541
|
+
tokensAfter: optNum(input.tokensAfter) ?? 0,
|
|
542
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
543
|
+
});
|
|
544
|
+
return { result };
|
|
545
|
+
},
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
// ===========================================================================
|
|
549
|
+
// Continuity, identity operations
|
|
550
|
+
// ===========================================================================
|
|
551
|
+
|
|
552
|
+
defineOperation({
|
|
553
|
+
name: "continuity_audit_generate",
|
|
554
|
+
description: "Generate a continuity audit.",
|
|
555
|
+
schema: looseSchema,
|
|
556
|
+
handler: async (input, ctx) => {
|
|
557
|
+
const result = await ctx.service.continuityAuditGenerate({
|
|
558
|
+
period: optStr(input.period) as "weekly" | "monthly" | undefined,
|
|
559
|
+
key: optStr(input.key),
|
|
560
|
+
});
|
|
561
|
+
return { result };
|
|
562
|
+
},
|
|
563
|
+
});
|
|
564
|
+
|
|
565
|
+
defineOperation({
|
|
566
|
+
name: "continuity_incident_open",
|
|
567
|
+
description: "Open a continuity incident.",
|
|
568
|
+
schema: looseSchema,
|
|
569
|
+
handler: async (input, ctx) => {
|
|
570
|
+
const result = await ctx.service.continuityIncidentOpen({
|
|
571
|
+
symptom: optStr(input.symptom) ?? "",
|
|
572
|
+
namespace: optStr(input.namespace),
|
|
573
|
+
triggerWindow: optStr(input.triggerWindow),
|
|
574
|
+
suspectedCause: optStr(input.suspectedCause),
|
|
575
|
+
principal: ctx.authenticatedPrincipal,
|
|
576
|
+
});
|
|
577
|
+
return { result };
|
|
578
|
+
},
|
|
579
|
+
});
|
|
580
|
+
|
|
581
|
+
defineOperation({
|
|
582
|
+
name: "continuity_incident_close",
|
|
583
|
+
description: "Close a continuity incident.",
|
|
584
|
+
schema: looseSchema,
|
|
585
|
+
handler: async (input, ctx) => {
|
|
586
|
+
const result = await ctx.service.continuityIncidentClose({
|
|
587
|
+
id: optStr(input.id) ?? "",
|
|
588
|
+
namespace: optStr(input.namespace),
|
|
589
|
+
fixApplied: optStr(input.fixApplied) ?? "",
|
|
590
|
+
verificationResult: optStr(input.verificationResult) ?? "",
|
|
591
|
+
preventiveRule: optStr(input.preventiveRule),
|
|
592
|
+
principal: ctx.authenticatedPrincipal,
|
|
593
|
+
});
|
|
594
|
+
return { result };
|
|
595
|
+
},
|
|
596
|
+
});
|
|
597
|
+
|
|
598
|
+
defineOperation({
|
|
599
|
+
name: "continuity_incident_list",
|
|
600
|
+
description: "List continuity incidents.",
|
|
601
|
+
schema: looseSchema,
|
|
602
|
+
handler: async (input, ctx) => {
|
|
603
|
+
const result = await ctx.service.continuityIncidentList({
|
|
604
|
+
state: optStr(input.state) as "all" | "open" | "closed" | undefined,
|
|
605
|
+
namespace: optStr(input.namespace),
|
|
606
|
+
limit: optNum(input.limit),
|
|
607
|
+
principal: ctx.authenticatedPrincipal,
|
|
608
|
+
});
|
|
609
|
+
return { result };
|
|
610
|
+
},
|
|
611
|
+
});
|
|
612
|
+
|
|
613
|
+
defineOperation({
|
|
614
|
+
name: "continuity_loop_add_or_update",
|
|
615
|
+
description: "Add or update a continuity loop.",
|
|
616
|
+
schema: looseSchema,
|
|
617
|
+
handler: async (input, ctx) => {
|
|
618
|
+
const result = await ctx.service.continuityLoopAddOrUpdate({
|
|
619
|
+
id: optStr(input.id) ?? "",
|
|
620
|
+
cadence: optStr(input.cadence) as "daily" | "weekly" | "monthly" | "quarterly",
|
|
621
|
+
purpose: optStr(input.purpose) ?? "",
|
|
622
|
+
status: optStr(input.status) as "active" | "paused" | "retired",
|
|
623
|
+
killCondition: optStr(input.killCondition) ?? "",
|
|
624
|
+
namespace: optStr(input.namespace),
|
|
625
|
+
lastReviewed: optStr(input.lastReviewed),
|
|
626
|
+
notes: optStr(input.notes),
|
|
627
|
+
principal: ctx.authenticatedPrincipal,
|
|
628
|
+
});
|
|
629
|
+
return { result };
|
|
630
|
+
},
|
|
631
|
+
});
|
|
632
|
+
|
|
633
|
+
defineOperation({
|
|
634
|
+
name: "continuity_loop_review",
|
|
635
|
+
description: "Review a continuity loop.",
|
|
636
|
+
schema: looseSchema,
|
|
637
|
+
handler: async (input, ctx) => {
|
|
638
|
+
const result = await ctx.service.continuityLoopReview({
|
|
639
|
+
id: optStr(input.id) ?? "",
|
|
640
|
+
namespace: optStr(input.namespace),
|
|
641
|
+
status: optStr(input.status) as "active" | "paused" | "retired" | undefined,
|
|
642
|
+
notes: optStr(input.notes),
|
|
643
|
+
reviewedAt: optStr(input.reviewedAt),
|
|
644
|
+
principal: ctx.authenticatedPrincipal,
|
|
645
|
+
});
|
|
646
|
+
return { result };
|
|
647
|
+
},
|
|
648
|
+
});
|
|
649
|
+
|
|
650
|
+
defineOperation({
|
|
651
|
+
name: "identity_anchor_get",
|
|
652
|
+
description: "Get identity anchor.",
|
|
653
|
+
schema: looseSchema,
|
|
654
|
+
handler: async (input, ctx) => {
|
|
655
|
+
const result = await ctx.service.identityAnchorGet({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal });
|
|
656
|
+
return { result };
|
|
657
|
+
},
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
defineOperation({
|
|
661
|
+
name: "identity_anchor_update",
|
|
662
|
+
description: "Update identity anchor.",
|
|
663
|
+
schema: looseSchema,
|
|
664
|
+
handler: async (input, ctx) => {
|
|
665
|
+
const result = await ctx.service.identityAnchorUpdate({
|
|
666
|
+
namespace: optStr(input.namespace),
|
|
667
|
+
identityTraits: optStr(input.identityTraits) ?? "",
|
|
668
|
+
communicationPreferences: optStr(input.communicationPreferences) ?? "",
|
|
669
|
+
operatingPrinciples: optStr(input.operatingPrinciples) ?? "",
|
|
670
|
+
continuityNotes: optStr(input.continuityNotes) ?? "",
|
|
671
|
+
});
|
|
672
|
+
return { result };
|
|
673
|
+
},
|
|
674
|
+
});
|
|
675
|
+
|
|
676
|
+
defineOperation({
|
|
677
|
+
name: "memory_identity",
|
|
678
|
+
description: "Get memory identity.",
|
|
679
|
+
schema: looseSchema,
|
|
680
|
+
handler: async (input, ctx) => {
|
|
681
|
+
const result = await ctx.service.memoryIdentity({ namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal });
|
|
682
|
+
return { result };
|
|
683
|
+
},
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
// ===========================================================================
|
|
687
|
+
// Work, shared-context, compounding, compression operations
|
|
688
|
+
// ===========================================================================
|
|
689
|
+
|
|
690
|
+
defineOperation({
|
|
691
|
+
name: "work_task",
|
|
692
|
+
description: "Manage a work task.",
|
|
693
|
+
schema: looseSchema,
|
|
694
|
+
handler: async (input, ctx) => {
|
|
695
|
+
const result = await ctx.service.workTask({
|
|
696
|
+
action: optStr(input.action) as "update" | "list" | "get" | "create" | "delete" | "transition",
|
|
697
|
+
id: optStr(input.id) ?? "",
|
|
698
|
+
title: optStr(input.title),
|
|
699
|
+
description: optStr(input.description),
|
|
700
|
+
status: optStr(input.status),
|
|
701
|
+
priority: optStr(input.priority),
|
|
702
|
+
owner: optStr(input.owner),
|
|
703
|
+
assignee: optStr(input.assignee),
|
|
704
|
+
projectId: optStr(input.projectId),
|
|
705
|
+
tags: optStrArr(input.tags),
|
|
706
|
+
dueAt: optStr(input.dueAt),
|
|
707
|
+
});
|
|
708
|
+
return { result };
|
|
709
|
+
},
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
defineOperation({
|
|
713
|
+
name: "work_project",
|
|
714
|
+
description: "Manage a work project.",
|
|
715
|
+
schema: looseSchema,
|
|
716
|
+
handler: async (input, ctx) => {
|
|
717
|
+
const result = await ctx.service.workProject({
|
|
718
|
+
action: optStr(input.action) as "update" | "list" | "get" | "create" | "delete" | "link_task",
|
|
719
|
+
id: optStr(input.id) ?? "",
|
|
720
|
+
name: optStr(input.name),
|
|
721
|
+
description: optStr(input.description),
|
|
722
|
+
status: optStr(input.status),
|
|
723
|
+
owner: optStr(input.owner),
|
|
724
|
+
tags: optStrArr(input.tags),
|
|
725
|
+
taskId: optStr(input.taskId),
|
|
726
|
+
projectId: optStr(input.projectId),
|
|
727
|
+
});
|
|
728
|
+
return { result };
|
|
729
|
+
},
|
|
730
|
+
});
|
|
731
|
+
|
|
732
|
+
defineOperation({
|
|
733
|
+
name: "work_board",
|
|
734
|
+
description: "Manage a work board.",
|
|
735
|
+
schema: looseSchema,
|
|
736
|
+
handler: async (input, ctx) => {
|
|
737
|
+
const result = await ctx.service.workBoard({
|
|
738
|
+
action: optStr(input.action) as "export_markdown" | "export_snapshot" | "import_snapshot",
|
|
739
|
+
projectId: optStr(input.projectId) ?? "",
|
|
740
|
+
snapshotJson: optStr(input.snapshotJson) ?? "",
|
|
741
|
+
linkToMemory: input.linkToMemory === true,
|
|
742
|
+
});
|
|
743
|
+
return { result };
|
|
744
|
+
},
|
|
745
|
+
});
|
|
746
|
+
|
|
747
|
+
defineOperation({
|
|
748
|
+
name: "shared_context_write_output",
|
|
749
|
+
description: "Write shared context output.",
|
|
750
|
+
schema: looseSchema,
|
|
751
|
+
handler: async (input, ctx) => {
|
|
752
|
+
const result = await ctx.service.sharedContextWriteOutput({
|
|
753
|
+
agentId: optStr(input.agentId) ?? "",
|
|
754
|
+
title: optStr(input.title) ?? "",
|
|
755
|
+
content: optStr(input.content) ?? "",
|
|
756
|
+
});
|
|
757
|
+
return { result };
|
|
758
|
+
},
|
|
759
|
+
});
|
|
760
|
+
|
|
761
|
+
defineOperation({
|
|
762
|
+
name: "shared_feedback_record",
|
|
763
|
+
description: "Record shared feedback.",
|
|
764
|
+
schema: looseSchema,
|
|
765
|
+
handler: async (input, ctx) => {
|
|
766
|
+
const result = await ctx.service.sharedFeedbackRecord({
|
|
767
|
+
agent: optStr(input.agent) ?? "",
|
|
768
|
+
decision: optStr(input.decision) as "rejected" | "approved" | "approved_with_feedback",
|
|
769
|
+
reason: optStr(input.reason) ?? "",
|
|
770
|
+
date: optStr(input.date) ?? "",
|
|
771
|
+
learning: optStr(input.learning) ?? "",
|
|
772
|
+
outcome: optStr(input.outcome) ?? "",
|
|
773
|
+
severity: optStr(input.severity) as "high" | "low" | "medium" | undefined,
|
|
774
|
+
confidence: optNum(input.confidence),
|
|
775
|
+
workflow: optStr(input.workflow),
|
|
776
|
+
tags: optStrArr(input.tags),
|
|
777
|
+
evidenceWindowStart: optStr(input.evidenceWindowStart),
|
|
778
|
+
evidenceWindowEnd: optStr(input.evidenceWindowEnd),
|
|
779
|
+
refs: optStrArr(input.refs),
|
|
780
|
+
});
|
|
781
|
+
return { result };
|
|
782
|
+
},
|
|
783
|
+
});
|
|
784
|
+
|
|
785
|
+
defineOperation({
|
|
786
|
+
name: "shared_priorities_append",
|
|
787
|
+
description: "Append to shared priorities.",
|
|
788
|
+
schema: looseSchema,
|
|
789
|
+
handler: async (input, ctx) => {
|
|
790
|
+
const result = await ctx.service.sharedPrioritiesAppend({
|
|
791
|
+
agentId: optStr(input.agentId) ?? "",
|
|
792
|
+
text: optStr(input.text) ?? "",
|
|
793
|
+
});
|
|
794
|
+
return { result };
|
|
795
|
+
},
|
|
796
|
+
});
|
|
797
|
+
|
|
798
|
+
defineOperation({
|
|
799
|
+
name: "shared_context_cross_signals_run",
|
|
800
|
+
description: "Run shared context cross signals.",
|
|
801
|
+
schema: looseSchema,
|
|
802
|
+
handler: async (input, ctx) => {
|
|
803
|
+
const result = await ctx.service.sharedContextCrossSignalsRun({ date: optStr(input.date) });
|
|
804
|
+
return { result };
|
|
805
|
+
},
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
defineOperation({
|
|
809
|
+
name: "shared_context_curate_daily",
|
|
810
|
+
description: "Curate daily shared context.",
|
|
811
|
+
schema: looseSchema,
|
|
812
|
+
handler: async (input, ctx) => {
|
|
813
|
+
const result = await ctx.service.sharedContextCurateDaily({ date: optStr(input.date) });
|
|
814
|
+
return { result };
|
|
815
|
+
},
|
|
816
|
+
});
|
|
817
|
+
|
|
818
|
+
defineOperation({
|
|
819
|
+
name: "compounding_weekly_synthesize",
|
|
820
|
+
description: "Weekly compound synthesis.",
|
|
821
|
+
schema: looseSchema,
|
|
822
|
+
handler: async (input, ctx) => {
|
|
823
|
+
const result = await ctx.service.compoundingWeeklySynthesize({ weekId: optStr(input.weekId) });
|
|
824
|
+
return { result };
|
|
825
|
+
},
|
|
826
|
+
});
|
|
827
|
+
|
|
828
|
+
defineOperation({
|
|
829
|
+
name: "compounding_promote_candidate",
|
|
830
|
+
description: "Promote a compounding candidate.",
|
|
831
|
+
schema: looseSchema,
|
|
832
|
+
handler: async (input, ctx) => {
|
|
833
|
+
const result = await ctx.service.compoundingPromoteCandidate({
|
|
834
|
+
weekId: optStr(input.weekId) ?? "",
|
|
835
|
+
candidateId: optStr(input.candidateId) ?? "",
|
|
836
|
+
dryRun: input.dryRun === true,
|
|
837
|
+
});
|
|
838
|
+
return { result };
|
|
839
|
+
},
|
|
840
|
+
});
|
|
841
|
+
|
|
842
|
+
defineOperation({
|
|
843
|
+
name: "compression_guidelines_optimize",
|
|
844
|
+
description: "Optimize compression guidelines.",
|
|
845
|
+
schema: looseSchema,
|
|
846
|
+
handler: async (input, ctx) => {
|
|
847
|
+
const result = await ctx.service.compressionGuidelinesOptimize({
|
|
848
|
+
dryRun: input.dryRun === true,
|
|
849
|
+
eventLimit: optNum(input.eventLimit),
|
|
850
|
+
});
|
|
851
|
+
return { result };
|
|
852
|
+
},
|
|
853
|
+
});
|
|
854
|
+
|
|
855
|
+
defineOperation({
|
|
856
|
+
name: "compression_guidelines_activate",
|
|
857
|
+
description: "Activate compression guidelines.",
|
|
858
|
+
schema: looseSchema,
|
|
859
|
+
handler: async (input, ctx) => {
|
|
860
|
+
const result = await ctx.service.compressionGuidelinesActivate({
|
|
861
|
+
expectedContentHash: optStr(input.expectedContentHash) ?? "",
|
|
862
|
+
expectedGuidelineVersion: optNum(input.expectedGuidelineVersion),
|
|
863
|
+
});
|
|
864
|
+
return { result };
|
|
865
|
+
},
|
|
866
|
+
});
|
|
867
|
+
|
|
868
|
+
// ===========================================================================
|
|
869
|
+
// Memory read/debug, graph, feedback, promote, outcome operations
|
|
870
|
+
// ===========================================================================
|
|
871
|
+
|
|
872
|
+
defineOperation({
|
|
873
|
+
name: "memory_profile",
|
|
874
|
+
description: "Get the memory profile.",
|
|
875
|
+
schema: looseSchema,
|
|
876
|
+
handler: async (input, ctx) => {
|
|
877
|
+
const result = await ctx.service.memoryProfile(optStr(input.namespace), ctx.authenticatedPrincipal);
|
|
878
|
+
return { result };
|
|
879
|
+
},
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
defineOperation({
|
|
883
|
+
name: "memory_entities_list",
|
|
884
|
+
description: "List memory entities.",
|
|
885
|
+
schema: looseSchema,
|
|
886
|
+
handler: async (input, ctx) => {
|
|
887
|
+
const result = await ctx.service.memoryEntitiesList(optStr(input.namespace), ctx.authenticatedPrincipal);
|
|
888
|
+
return { result };
|
|
889
|
+
},
|
|
890
|
+
});
|
|
891
|
+
|
|
892
|
+
defineOperation({
|
|
893
|
+
name: "memory_questions",
|
|
894
|
+
description: "List memory questions.",
|
|
895
|
+
schema: looseSchema,
|
|
896
|
+
handler: async (input, ctx) => {
|
|
897
|
+
const result = await ctx.service.memoryQuestions(optStr(input.namespace), ctx.authenticatedPrincipal);
|
|
898
|
+
return { result };
|
|
899
|
+
},
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
defineOperation({
|
|
903
|
+
name: "memory_last_recall",
|
|
904
|
+
description: "Get last recall snapshot.",
|
|
905
|
+
schema: looseSchema,
|
|
906
|
+
handler: async (input, ctx) => {
|
|
907
|
+
const result = await ctx.service.lastRecallSnapshot(optStr(input.sessionKey));
|
|
908
|
+
return { result };
|
|
909
|
+
},
|
|
910
|
+
});
|
|
911
|
+
|
|
912
|
+
defineOperation({
|
|
913
|
+
name: "memory_intent_debug",
|
|
914
|
+
description: "Debug memory intent.",
|
|
915
|
+
schema: looseSchema,
|
|
916
|
+
handler: async (input, ctx) => {
|
|
917
|
+
const result = await ctx.service.intentDebug(optStr(input.namespace));
|
|
918
|
+
return { result };
|
|
919
|
+
},
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
defineOperation({
|
|
923
|
+
name: "memory_qmd_debug",
|
|
924
|
+
description: "Debug QMD.",
|
|
925
|
+
schema: looseSchema,
|
|
926
|
+
handler: async (input, ctx) => {
|
|
927
|
+
const result = await ctx.service.qmdDebug(optStr(input.namespace));
|
|
928
|
+
return { result };
|
|
929
|
+
},
|
|
930
|
+
});
|
|
931
|
+
|
|
932
|
+
defineOperation({
|
|
933
|
+
name: "memory_graph_explain",
|
|
934
|
+
description: "Explain the memory graph.",
|
|
935
|
+
schema: looseSchema,
|
|
936
|
+
handler: async (input, ctx) => {
|
|
937
|
+
const result = await ctx.service.graphExplainLastRecall(optStr(input.namespace));
|
|
938
|
+
return { result };
|
|
939
|
+
},
|
|
940
|
+
});
|
|
941
|
+
|
|
942
|
+
defineOperation({
|
|
943
|
+
name: "graph_snapshot",
|
|
944
|
+
description: "Get a graph snapshot.",
|
|
945
|
+
schema: looseSchema,
|
|
946
|
+
handler: async (input, ctx) => {
|
|
947
|
+
const result = await ctx.service.graphSnapshot({
|
|
948
|
+
namespace: optStr(input.namespace),
|
|
949
|
+
limit: optNum(input.limit),
|
|
950
|
+
since: optStr(input.since),
|
|
951
|
+
focusNodeId: optStr(input.focusNodeId),
|
|
952
|
+
categories: optStrArr(input.categories),
|
|
953
|
+
}, ctx.authenticatedPrincipal);
|
|
954
|
+
return { result };
|
|
955
|
+
},
|
|
956
|
+
});
|
|
957
|
+
|
|
958
|
+
defineOperation({
|
|
959
|
+
name: "memory_feedback",
|
|
960
|
+
description: "Record memory feedback.",
|
|
961
|
+
schema: looseSchema,
|
|
962
|
+
handler: async (input, ctx) => {
|
|
963
|
+
const result = await ctx.service.memoryFeedback({
|
|
964
|
+
memoryId: optStr(input.memoryId) ?? "",
|
|
965
|
+
vote: optStr(input.vote) as "up" | "down",
|
|
966
|
+
note: optStr(input.note),
|
|
967
|
+
});
|
|
968
|
+
return { result };
|
|
969
|
+
},
|
|
970
|
+
});
|
|
971
|
+
|
|
972
|
+
defineOperation({
|
|
973
|
+
name: "memory_promote",
|
|
974
|
+
description: "Promote a memory.",
|
|
975
|
+
schema: looseSchema,
|
|
976
|
+
handler: async (input, ctx) => {
|
|
977
|
+
const result = await ctx.service.memoryPromote({
|
|
978
|
+
memoryId: optStr(input.memoryId) ?? "",
|
|
979
|
+
namespace: optStr(input.namespace),
|
|
980
|
+
sessionKey: optStr(input.sessionKey),
|
|
981
|
+
principal: ctx.authenticatedPrincipal,
|
|
982
|
+
});
|
|
983
|
+
return { result };
|
|
984
|
+
},
|
|
985
|
+
});
|
|
986
|
+
|
|
987
|
+
defineOperation({
|
|
988
|
+
name: "memory_outcome",
|
|
989
|
+
description: "Record a memory outcome.",
|
|
990
|
+
schema: looseSchema,
|
|
991
|
+
handler: async (input, ctx) => {
|
|
992
|
+
const result = await ctx.service.memoryOutcome({
|
|
993
|
+
memoryId: optStr(input.memoryId) ?? "",
|
|
994
|
+
outcome: optStr(input.outcome) as "success" | "failure",
|
|
995
|
+
namespace: optStr(input.namespace),
|
|
996
|
+
sessionKey: optStr(input.sessionKey),
|
|
997
|
+
timestamp: optStr(input.timestamp),
|
|
998
|
+
principal: ctx.authenticatedPrincipal,
|
|
999
|
+
});
|
|
1000
|
+
return { result };
|
|
1001
|
+
},
|
|
1002
|
+
});
|
|
1003
|
+
|
|
1004
|
+
defineOperation({
|
|
1005
|
+
name: "memory_action_apply",
|
|
1006
|
+
description: "Apply a memory action.",
|
|
1007
|
+
schema: looseSchema,
|
|
1008
|
+
handler: async (input, ctx) => {
|
|
1009
|
+
const result = await ctx.service.memoryActionApply({
|
|
1010
|
+
action: optStr(input.action) ?? "",
|
|
1011
|
+
outcome: optStr(input.outcome),
|
|
1012
|
+
reason: optStr(input.reason),
|
|
1013
|
+
memoryId: optStr(input.memoryId) ?? "",
|
|
1014
|
+
namespace: optStr(input.namespace),
|
|
1015
|
+
sessionKey: optStr(input.sessionKey),
|
|
1016
|
+
content: optStr(input.content),
|
|
1017
|
+
category: optStr(input.category),
|
|
1018
|
+
linkTargetId: optStr(input.linkTargetId),
|
|
1019
|
+
linkType: optStr(input.linkType),
|
|
1020
|
+
linkStrength: optNum(input.linkStrength),
|
|
1021
|
+
artifactType: optStr(input.artifactType),
|
|
1022
|
+
execute: input.execute === true,
|
|
1023
|
+
sourcePrompt: optStr(input.sourcePrompt),
|
|
1024
|
+
dryRun: input.dryRun === true,
|
|
1025
|
+
principal: ctx.authenticatedPrincipal,
|
|
1026
|
+
});
|
|
1027
|
+
return { result };
|
|
1028
|
+
},
|
|
1029
|
+
});
|
|
1030
|
+
|
|
1031
|
+
defineOperation({
|
|
1032
|
+
name: "context_checkpoint",
|
|
1033
|
+
description: "Create a context checkpoint.",
|
|
1034
|
+
schema: looseSchema,
|
|
1035
|
+
handler: async (input, ctx) => {
|
|
1036
|
+
const result = await ctx.service.contextCheckpoint({
|
|
1037
|
+
sessionKey: optStr(input.sessionKey) ?? "",
|
|
1038
|
+
context: optStr(input.context) ?? "",
|
|
1039
|
+
namespace: optStr(input.namespace),
|
|
1040
|
+
principal: ctx.authenticatedPrincipal,
|
|
1041
|
+
});
|
|
1042
|
+
return { result };
|
|
1043
|
+
},
|
|
1044
|
+
});
|
|
1045
|
+
|
|
1046
|
+
defineOperation({
|
|
1047
|
+
name: "briefing",
|
|
1048
|
+
description: "Get a daily context briefing.",
|
|
1049
|
+
schema: looseSchema,
|
|
1050
|
+
handler: async (input, ctx) => {
|
|
1051
|
+
const result = await ctx.service.briefing({
|
|
1052
|
+
since: optStr(input.since),
|
|
1053
|
+
focus: optStr(input.focus),
|
|
1054
|
+
namespace: optStr(input.namespace),
|
|
1055
|
+
format: optStr(input.format) as "json" | "markdown" | undefined,
|
|
1056
|
+
maxFollowups: optNum(input.maxFollowups),
|
|
1057
|
+
principal: ctx.authenticatedPrincipal,
|
|
1058
|
+
});
|
|
1059
|
+
return { result };
|
|
1060
|
+
},
|
|
1061
|
+
});
|
|
1062
|
+
|
|
1063
|
+
// ===========================================================================
|
|
1064
|
+
// Contradiction review, scan, graph-edge-decay (dynamic-import handlers)
|
|
1065
|
+
// ===========================================================================
|
|
1066
|
+
|
|
1067
|
+
defineOperation({
|
|
1068
|
+
name: "review_list",
|
|
1069
|
+
description: "List contradiction review pairs.",
|
|
1070
|
+
schema: looseSchema,
|
|
1071
|
+
handler: async (input, ctx) => {
|
|
1072
|
+
const { isDefaultReviewNamespace, listPairs } = await import("./contradiction/contradiction-review.js");
|
|
1073
|
+
const VALID_FILTERS = new Set(["all", "unresolved", "contradicts", "independent", "duplicates", "needs-user"]);
|
|
1074
|
+
const rawFilter = optStr(input.filter) ?? "unresolved";
|
|
1075
|
+
if (!VALID_FILTERS.has(rawFilter)) {
|
|
1076
|
+
throw new EngramAccessInputError("Invalid filter '" + rawFilter + "'. Valid: " + [...VALID_FILTERS].join(", "));
|
|
1077
|
+
}
|
|
1078
|
+
const filter = rawFilter as "all" | "unresolved" | "contradicts" | "independent" | "duplicates" | "needs-user";
|
|
1079
|
+
const ns = optStr(input.namespace);
|
|
1080
|
+
const limit = optNum(input.limit) ?? 50;
|
|
1081
|
+
const resolved = await ctx.service.getReadableStorageForNamespace(ns, ctx.authenticatedPrincipal);
|
|
1082
|
+
const reviewNamespace = ctx.service.configRef.namespacesEnabled ? resolved.namespace : undefined;
|
|
1083
|
+
const includeUnscopedForNamespace = Boolean(
|
|
1084
|
+
reviewNamespace && isDefaultReviewNamespace(ctx.service.configRef.defaultNamespace, ns, reviewNamespace),
|
|
1085
|
+
);
|
|
1086
|
+
const result = await listPairs(ctx.service.memoryDir, { filter, namespace: reviewNamespace, includeUnscopedForNamespace, limit });
|
|
1087
|
+
return { result };
|
|
1088
|
+
},
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
defineOperation({
|
|
1092
|
+
name: "review_resolve",
|
|
1093
|
+
description: "Resolve a contradiction pair.",
|
|
1094
|
+
schema: looseSchema,
|
|
1095
|
+
handler: async (input, ctx) => {
|
|
1096
|
+
const pairId = defStr(input.pairId, "");
|
|
1097
|
+
const verb = defStr(input.verb, "");
|
|
1098
|
+
if (!pairId) throw new EngramAccessInputError("pairId is required");
|
|
1099
|
+
if (!verb) throw new EngramAccessInputError("verb is required");
|
|
1100
|
+
const { isValidResolutionVerb, executeResolution } = await import("./contradiction/resolution.js");
|
|
1101
|
+
if (!isValidResolutionVerb(verb)) throw new EngramAccessInputError("Invalid verb: " + verb + ". Must be one of: keep-a, keep-b, merge, both-valid, needs-more-context");
|
|
1102
|
+
const result = await executeResolution(ctx.service.memoryDir, ctx.service.storageRef, pairId, verb, {
|
|
1103
|
+
mergedMemoryId: optStr(input.mergedMemoryId),
|
|
1104
|
+
mergedContent: optStr(input.mergedContent),
|
|
1105
|
+
storageForNamespace: async (namespace: string | undefined) => {
|
|
1106
|
+
const r = await ctx.service.getWritableStorageForNamespace(namespace, ctx.authenticatedPrincipal);
|
|
1107
|
+
return r.storage;
|
|
1108
|
+
},
|
|
1109
|
+
onMergedMemoryWritten: () => { /* #1522: catalog touch at storage chokepoint */ },
|
|
1110
|
+
});
|
|
1111
|
+
return { result };
|
|
1112
|
+
},
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
defineOperation({
|
|
1116
|
+
name: "contradiction_scan_run",
|
|
1117
|
+
description: "Run a contradiction scan.",
|
|
1118
|
+
schema: looseSchema,
|
|
1119
|
+
handler: async (input, ctx) => {
|
|
1120
|
+
const { runContradictionScan } = await import("./contradiction/contradiction-scan.js");
|
|
1121
|
+
const result = await runContradictionScan({
|
|
1122
|
+
storage: ctx.service.storageRef,
|
|
1123
|
+
config: ctx.service.configRef,
|
|
1124
|
+
memoryDir: ctx.service.memoryDir,
|
|
1125
|
+
embeddingLookupFactory: ctx.service.embeddingLookupFactoryRef,
|
|
1126
|
+
storageForNamespace: (namespace: string | undefined) =>
|
|
1127
|
+
ctx.service.getWritableStorageForNamespace(namespace ?? undefined, ctx.authenticatedPrincipal),
|
|
1128
|
+
localLlm: ctx.service.localLlmRef,
|
|
1129
|
+
fallbackLlm: ctx.service.fallbackLlmRef,
|
|
1130
|
+
namespace: optStr(input.namespace),
|
|
1131
|
+
});
|
|
1132
|
+
return { result };
|
|
1133
|
+
},
|
|
1134
|
+
});
|
|
1135
|
+
|
|
1136
|
+
defineOperation({
|
|
1137
|
+
name: "graph_edge_decay_run",
|
|
1138
|
+
description: "Run graph edge decay maintenance.",
|
|
1139
|
+
schema: looseSchema,
|
|
1140
|
+
handler: async (input, ctx) => {
|
|
1141
|
+
const cfg = ctx.service.configRef;
|
|
1142
|
+
if (!cfg.graphEdgeDecayEnabled) {
|
|
1143
|
+
return { result: { ranAt: new Date().toISOString(), disabled: true, reason: "graphEdgeDecayEnabled is false" } };
|
|
1144
|
+
}
|
|
1145
|
+
const { runGraphEdgeDecayMaintenanceAcrossNamespaces } = await import("./maintenance/graph-edge-decay.js");
|
|
1146
|
+
const dryRun = input.dryRun === true;
|
|
1147
|
+
const results = await runGraphEdgeDecayMaintenanceAcrossNamespaces(ctx.service.memoryDir, {
|
|
1148
|
+
windowMs: cfg.graphEdgeDecayWindowMs,
|
|
1149
|
+
perWindow: cfg.graphEdgeDecayPerWindow,
|
|
1150
|
+
floor: cfg.graphEdgeDecayFloor,
|
|
1151
|
+
visibilityThreshold: cfg.graphEdgeDecayVisibilityThreshold,
|
|
1152
|
+
dryRun,
|
|
1153
|
+
namespacesEnabled: cfg.namespacesEnabled === true,
|
|
1154
|
+
defaultNamespace: cfg.defaultNamespace,
|
|
1155
|
+
});
|
|
1156
|
+
return { result: { results } };
|
|
1157
|
+
},
|
|
1158
|
+
});
|
|
1159
|
+
|
|
1160
|
+
// ===========================================================================
|
|
1161
|
+
// Remaining operations: summarize, profiling, connectors, peers, console, dreams
|
|
1162
|
+
// ===========================================================================
|
|
1163
|
+
|
|
1164
|
+
defineOperation({
|
|
1165
|
+
name: "memory_summarize_hourly",
|
|
1166
|
+
description: "Run hourly memory summarization.",
|
|
1167
|
+
schema: looseSchema,
|
|
1168
|
+
handler: async (_input, ctx) => ({ result: await ctx.service.memorySummarizeHourly() }),
|
|
1169
|
+
});
|
|
1170
|
+
|
|
1171
|
+
defineOperation({
|
|
1172
|
+
name: "conversation_index_update",
|
|
1173
|
+
description: "Update the conversation index.",
|
|
1174
|
+
schema: looseSchema,
|
|
1175
|
+
handler: async (input, ctx) => {
|
|
1176
|
+
const result = await ctx.service.conversationIndexUpdate({
|
|
1177
|
+
sessionKey: optStr(input.sessionKey),
|
|
1178
|
+
hours: optNum(input.hours),
|
|
1179
|
+
embed: optBool(input.embed),
|
|
1180
|
+
});
|
|
1181
|
+
return { result };
|
|
1182
|
+
},
|
|
1183
|
+
});
|
|
1184
|
+
|
|
1185
|
+
defineOperation({
|
|
1186
|
+
name: "profiling_report",
|
|
1187
|
+
description: "Get a profiling report.",
|
|
1188
|
+
schema: looseSchema,
|
|
1189
|
+
handler: async (input, ctx) => {
|
|
1190
|
+
const result = await ctx.service.profilingReport({
|
|
1191
|
+
format: optStr(input.format),
|
|
1192
|
+
limit: optNum(input.limit),
|
|
1193
|
+
});
|
|
1194
|
+
return { result };
|
|
1195
|
+
},
|
|
1196
|
+
});
|
|
1197
|
+
|
|
1198
|
+
defineOperation({
|
|
1199
|
+
name: "live_connectors_run",
|
|
1200
|
+
description: "Run live connectors.",
|
|
1201
|
+
schema: looseSchema,
|
|
1202
|
+
handler: async (input, ctx) => {
|
|
1203
|
+
const result = await ctx.service.liveConnectorsRun(
|
|
1204
|
+
{ authenticatedPrincipal: ctx.authenticatedPrincipal, force: input.force === true },
|
|
1205
|
+
ctx.authenticatedPrincipal,
|
|
1206
|
+
);
|
|
1207
|
+
return { result };
|
|
1208
|
+
},
|
|
1209
|
+
});
|
|
1210
|
+
|
|
1211
|
+
defineOperation({
|
|
1212
|
+
name: "peer_list",
|
|
1213
|
+
description: "List peers.",
|
|
1214
|
+
schema: looseSchema,
|
|
1215
|
+
handler: async (_input, ctx) => ({ result: await ctx.service.peerList() }),
|
|
1216
|
+
});
|
|
1217
|
+
|
|
1218
|
+
defineOperation({
|
|
1219
|
+
name: "peer_get",
|
|
1220
|
+
description: "Get a peer.",
|
|
1221
|
+
schema: looseSchema,
|
|
1222
|
+
handler: async (input, ctx) => {
|
|
1223
|
+
const result = await ctx.service.peerGet(defStr(input.id, ""));
|
|
1224
|
+
return { result };
|
|
1225
|
+
},
|
|
1226
|
+
});
|
|
1227
|
+
|
|
1228
|
+
defineOperation({
|
|
1229
|
+
name: "peer_set",
|
|
1230
|
+
description: "Create or update a peer.",
|
|
1231
|
+
schema: looseSchema,
|
|
1232
|
+
handler: async (input, ctx) => {
|
|
1233
|
+
const result = await ctx.service.peerSet({
|
|
1234
|
+
id: optStr(input.id) ?? "",
|
|
1235
|
+
kind: optStr(input.kind),
|
|
1236
|
+
displayName: optStr(input.displayName),
|
|
1237
|
+
notes: optStr(input.notes),
|
|
1238
|
+
});
|
|
1239
|
+
return { result };
|
|
1240
|
+
},
|
|
1241
|
+
});
|
|
1242
|
+
|
|
1243
|
+
defineOperation({
|
|
1244
|
+
name: "peer_delete",
|
|
1245
|
+
description: "Delete a peer.",
|
|
1246
|
+
schema: looseSchema,
|
|
1247
|
+
handler: async (input, ctx) => {
|
|
1248
|
+
const result = await ctx.service.peerDelete(defStr(input.id, ""));
|
|
1249
|
+
return { result };
|
|
1250
|
+
},
|
|
1251
|
+
});
|
|
1252
|
+
|
|
1253
|
+
defineOperation({
|
|
1254
|
+
name: "peer_profile_get",
|
|
1255
|
+
description: "Get a peer profile.",
|
|
1256
|
+
schema: looseSchema,
|
|
1257
|
+
handler: async (input, ctx) => {
|
|
1258
|
+
const result = await ctx.service.peerProfileGet(optStr(input.id) ?? "");
|
|
1259
|
+
return { result };
|
|
1260
|
+
},
|
|
1261
|
+
});
|
|
1262
|
+
|
|
1263
|
+
defineOperation({
|
|
1264
|
+
name: "peer_forget",
|
|
1265
|
+
description: "Forget a peer.",
|
|
1266
|
+
schema: looseSchema,
|
|
1267
|
+
handler: async (input, ctx) => {
|
|
1268
|
+
const result = await ctx.service.peerForget(optStr(input.id) ?? "", { confirm: input.confirm === true || optStr(input.confirm) === "yes" ? "yes" : "" });
|
|
1269
|
+
return { result };
|
|
1270
|
+
},
|
|
1271
|
+
});
|
|
1272
|
+
|
|
1273
|
+
defineOperation({
|
|
1274
|
+
name: "console_state",
|
|
1275
|
+
description: "Get console state.",
|
|
1276
|
+
schema: looseSchema,
|
|
1277
|
+
handler: async (input, ctx) => {
|
|
1278
|
+
const result = await ctx.service.consoleState(optStr(input.namespace), ctx.authenticatedPrincipal);
|
|
1279
|
+
return { result };
|
|
1280
|
+
},
|
|
1281
|
+
});
|
|
1282
|
+
|
|
1283
|
+
defineOperation({
|
|
1284
|
+
name: "dreams_status",
|
|
1285
|
+
description: "Get dreams status.",
|
|
1286
|
+
schema: looseSchema,
|
|
1287
|
+
handler: async (input, ctx) => {
|
|
1288
|
+
const result = await ctx.service.dreamsStatus({
|
|
1289
|
+
windowHours: optNum(input.windowHours),
|
|
1290
|
+
namespace: optStr(input.namespace),
|
|
1291
|
+
principal: ctx.authenticatedPrincipal,
|
|
1292
|
+
});
|
|
1293
|
+
return { result };
|
|
1294
|
+
},
|
|
1295
|
+
});
|
|
1296
|
+
|
|
1297
|
+
defineOperation({
|
|
1298
|
+
name: "dreams_run",
|
|
1299
|
+
description: "Run dreams.",
|
|
1300
|
+
schema: looseSchema,
|
|
1301
|
+
handler: async (input, ctx) => {
|
|
1302
|
+
const result = await ctx.service.dreamsRun({
|
|
1303
|
+
phase: optStr(input.phase) as import("./types.js").DreamsPhase,
|
|
1304
|
+
dryRun: input.dryRun === true,
|
|
1305
|
+
namespace: optStr(input.namespace),
|
|
1306
|
+
authenticatedPrincipal: ctx.authenticatedPrincipal,
|
|
1307
|
+
});
|
|
1308
|
+
return { result };
|
|
1309
|
+
},
|
|
1310
|
+
});
|
|
1311
|
+
|
|
1312
|
+
// ===========================================================================
|
|
1313
|
+
// HTTP-only operations (routes with no direct MCP tool equivalent)
|
|
1314
|
+
// ===========================================================================
|
|
1315
|
+
|
|
1316
|
+
defineOperation({
|
|
1317
|
+
name: "offline_sync_snapshot",
|
|
1318
|
+
description: "Get or create an offline-sync snapshot.",
|
|
1319
|
+
schema: looseSchema,
|
|
1320
|
+
handler: async (_input, ctx) => {
|
|
1321
|
+
const result = await ctx.service.offlineSyncSnapshot();
|
|
1322
|
+
return { result };
|
|
1323
|
+
},
|
|
1324
|
+
});
|
|
1325
|
+
|
|
1326
|
+
defineOperation({
|
|
1327
|
+
name: "offline_sync_files",
|
|
1328
|
+
description: "List offline-sync files.",
|
|
1329
|
+
schema: looseSchema,
|
|
1330
|
+
handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncFiles({ paths: optStrArr(input.paths) ?? [], namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }),
|
|
1331
|
+
});
|
|
1332
|
+
|
|
1333
|
+
defineOperation({
|
|
1334
|
+
name: "offline_sync_file_content",
|
|
1335
|
+
description: "Read offline-sync file content.",
|
|
1336
|
+
schema: looseSchema,
|
|
1337
|
+
handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncFileContent({ path: optStr(input.path) ?? "", namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal, offset: optNum(input.offset), length: optNum(input.length) }) }),
|
|
1338
|
+
});
|
|
1339
|
+
|
|
1340
|
+
defineOperation({
|
|
1341
|
+
name: "offline_sync_apply_file_content",
|
|
1342
|
+
description: "Apply offline-sync file content.",
|
|
1343
|
+
schema: looseSchema,
|
|
1344
|
+
handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncApplyFileContent({ sourceId: optStr(input.sourceId) ?? "", path: optStr(input.path) ?? "", sha256: optStr(input.sha256) ?? "", bytes: optNum(input.bytes) ?? 0, mtimeMs: optNum(input.mtimeMs) ?? 0, offset: optNum(input.offset), baseSha256: optStr(input.baseSha256), content: Buffer.from(defStr(input.content, ""), "base64"), namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }),
|
|
1345
|
+
});
|
|
1346
|
+
|
|
1347
|
+
defineOperation({
|
|
1348
|
+
name: "offline_sync_apply",
|
|
1349
|
+
description: "Apply an offline-sync snapshot.",
|
|
1350
|
+
schema: looseSchema,
|
|
1351
|
+
handler: async (input, ctx) => ({ result: await ctx.service.offlineSyncApply({ changeset: input.changeset, namespace: optStr(input.namespace), principal: ctx.authenticatedPrincipal }) }),
|
|
1352
|
+
});
|
|
1353
|
+
|
|
1354
|
+
defineOperation({
|
|
1355
|
+
name: "lcm_status",
|
|
1356
|
+
description: "Get LCM status.",
|
|
1357
|
+
schema: looseSchema,
|
|
1358
|
+
handler: async (_input, ctx) => ({ result: await ctx.service.lcmStatus() }),
|
|
1359
|
+
});
|
|
1360
|
+
|
|
1361
|
+
defineOperation({
|
|
1362
|
+
name: "memory_list",
|
|
1363
|
+
description: "Browse/list memories (HTTP GET /memories).",
|
|
1364
|
+
schema: looseSchema,
|
|
1365
|
+
handler: async (input, ctx) => ({ result: await ctx.service.memoryBrowse() }),
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
defineOperation({
|
|
1369
|
+
name: "entity_list",
|
|
1370
|
+
description: "List entities (HTTP GET /entities).",
|
|
1371
|
+
schema: looseSchema,
|
|
1372
|
+
handler: async (input, ctx) => ({ result: await ctx.service.entityList() }),
|
|
1373
|
+
});
|
|
1374
|
+
|
|
1375
|
+
defineOperation({
|
|
1376
|
+
name: "maintenance_status",
|
|
1377
|
+
description: "Get maintenance status (HTTP GET /maintenance).",
|
|
1378
|
+
schema: looseSchema,
|
|
1379
|
+
handler: async (input, ctx) => ({ result: await ctx.service.maintenance() }),
|
|
1380
|
+
});
|
|
1381
|
+
|
|
1382
|
+
defineOperation({
|
|
1383
|
+
name: "quality_status",
|
|
1384
|
+
description: "Get quality status (HTTP GET /quality).",
|
|
1385
|
+
schema: looseSchema,
|
|
1386
|
+
handler: async (input, ctx) => ({ result: await ctx.service.quality() }),
|
|
1387
|
+
});
|
|
1388
|
+
|
|
1389
|
+
defineOperation({
|
|
1390
|
+
name: "trust_zones_status",
|
|
1391
|
+
description: "Get trust-zone status.",
|
|
1392
|
+
schema: looseSchema,
|
|
1393
|
+
handler: async (input, ctx) => ({ result: await ctx.service.trustZoneStatus() }),
|
|
1394
|
+
});
|
|
1395
|
+
|
|
1396
|
+
defineOperation({
|
|
1397
|
+
name: "trust_zones_records",
|
|
1398
|
+
description: "Browse trust-zone records.",
|
|
1399
|
+
schema: looseSchema,
|
|
1400
|
+
handler: async (input, ctx) => ({ result: await ctx.service.trustZoneBrowse({ namespace: optStr(input.namespace), limit: optNum(input.limit), offset: optNum(input.offset) }, ctx.authenticatedPrincipal) }),
|
|
1401
|
+
});
|
|
1402
|
+
|
|
1403
|
+
defineOperation({
|
|
1404
|
+
name: "review_disposition",
|
|
1405
|
+
description: "Apply a review disposition.",
|
|
1406
|
+
schema: looseSchema,
|
|
1407
|
+
handler: async (input, ctx) => ({ result: await ctx.service.reviewDisposition({ memoryId: optStr(input.memoryId) ?? "", status: (optStr(input.status) ?? "archived") as import("./access-service.js").EngramAccessReviewDispositionRequest["status"], reasonCode: optStr(input.reasonCode) ?? "", namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }),
|
|
1408
|
+
});
|
|
1409
|
+
|
|
1410
|
+
defineOperation({
|
|
1411
|
+
name: "trust_zones_promote",
|
|
1412
|
+
description: "Promote a trust-zone record.",
|
|
1413
|
+
schema: looseSchema,
|
|
1414
|
+
handler: async (input, ctx) => ({ result: await ctx.service.trustZonePromote({ recordId: optStr(input.recordId) ?? "", targetZone: (optStr(input.targetZone) ?? "working") as import("./trust-zones.js").TrustZoneName, promotionReason: optStr(input.promotionReason) ?? "", dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }),
|
|
1415
|
+
});
|
|
1416
|
+
|
|
1417
|
+
defineOperation({
|
|
1418
|
+
name: "trust_zones_demo_seed",
|
|
1419
|
+
description: "Seed demo trust-zone records.",
|
|
1420
|
+
schema: looseSchema,
|
|
1421
|
+
handler: async (input, ctx) => ({ result: await ctx.service.trustZoneDemoSeed({ scenario: optStr(input.scenario), dryRun: input.dryRun === true, namespace: optStr(input.namespace), authenticatedPrincipal: ctx.authenticatedPrincipal }) }),
|
|
1422
|
+
});
|
|
1423
|
+
|
|
1424
|
+
defineOperation({
|
|
1425
|
+
name: "citations_observed",
|
|
1426
|
+
description: "Record observed citations (HTTP POST /v1/citations/observed).",
|
|
1427
|
+
schema: looseSchema,
|
|
1428
|
+
handler: async (input, ctx) => {
|
|
1429
|
+
// The HTTP handler has complex citation-entry parsing; this operation
|
|
1430
|
+
// owns the shape validation boundary. The handler forwards the cleaned
|
|
1431
|
+
// input so the transport-specific entry parsing stays in the surface.
|
|
1432
|
+
return { result: { ok: true } };
|
|
1433
|
+
},
|
|
1434
|
+
});
|
|
1435
|
+
|
|
1436
|
+
defineOperation({
|
|
1437
|
+
name: "contradiction_detail",
|
|
1438
|
+
description: "Get a single contradiction pair detail (HTTP GET /review/contradictions/:id).",
|
|
1439
|
+
schema: looseSchema,
|
|
1440
|
+
handler: async (input, ctx) => {
|
|
1441
|
+
const { listPairs } = await import("./contradiction/contradiction-review.js");
|
|
1442
|
+
const result = await listPairs(ctx.service.memoryDir, {
|
|
1443
|
+
filter: "all" as const,
|
|
1444
|
+
namespace: optStr(input.namespace),
|
|
1445
|
+
includeUnscopedForNamespace: false,
|
|
1446
|
+
limit: 1,
|
|
1447
|
+
});
|
|
1448
|
+
return { result };
|
|
1449
|
+
},
|
|
1450
|
+
});
|
|
1451
|
+
|
|
1452
|
+
// ===========================================================================
|
|
1453
|
+
// SSE-stream operations (endpoint registration; streaming handled by transport)
|
|
1454
|
+
// ===========================================================================
|
|
1455
|
+
|
|
1456
|
+
defineOperation({
|
|
1457
|
+
name: "offline_sync_snapshot_stream",
|
|
1458
|
+
description: "Stream offline-sync snapshot updates (SSE).",
|
|
1459
|
+
schema: looseSchema,
|
|
1460
|
+
handler: async (_input, ctx) => ({ result: await ctx.service.offlineSyncSnapshotStream() }),
|
|
1461
|
+
});
|
|
1462
|
+
|
|
1463
|
+
defineOperation({
|
|
1464
|
+
name: "graph_events",
|
|
1465
|
+
description: "Stream graph mutation events (SSE). Endpoint registration only.",
|
|
1466
|
+
schema: looseSchema,
|
|
1467
|
+
handler: async (_input, _ctx) => ({ result: { stream: "sse" } }),
|
|
1468
|
+
});
|