@remnic/core 9.3.624 → 9.3.626
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-cli.js +18 -16
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +12 -5
- package/dist/access-http.js +10 -9
- package/dist/access-mcp.d.ts +5 -5
- package/dist/access-mcp.js +8 -8
- package/dist/access-schema.d.ts +5 -5
- package/dist/{access-service-CBNEKjzN.d.ts → access-service-C_sfOHsX.d.ts} +26 -3
- package/dist/access-service.d.ts +5 -5
- package/dist/access-service.js +7 -7
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +2 -1
- package/dist/active-recall.js.map +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +4 -4
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +3 -3
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +4 -4
- package/dist/{chunk-7TPH6UZL.js → chunk-2RHI3FGV.js} +540 -17
- package/dist/chunk-2RHI3FGV.js.map +1 -0
- package/dist/{chunk-GYTVOLNX.js → chunk-3MNBW7R7.js} +2 -2
- package/dist/{chunk-QFQQFX2H.js → chunk-3R2UZV3U.js} +2 -2
- package/dist/{chunk-O4UNM6OR.js → chunk-532VCWYW.js} +2 -2
- package/dist/{chunk-2UFQYU5F.js → chunk-57QXN2CS.js} +2 -2
- package/dist/chunk-7WV3F5DQ.js +22 -0
- package/dist/chunk-7WV3F5DQ.js.map +1 -0
- package/dist/{chunk-RKW6QR7W.js → chunk-AZ4RI3QD.js} +1461 -78
- package/dist/chunk-AZ4RI3QD.js.map +1 -0
- package/dist/{chunk-KQFQ3IS5.js → chunk-F3FY3D3S.js} +43 -7
- package/dist/chunk-F3FY3D3S.js.map +1 -0
- package/dist/{chunk-4R4KTDIE.js → chunk-FPNQF475.js} +1 -1
- package/dist/chunk-FPNQF475.js.map +1 -0
- package/dist/{chunk-UGEBPVNI.js → chunk-GE7Q7KXP.js} +2 -2
- package/dist/{chunk-GLWW3EJQ.js → chunk-KB4MFBF5.js} +3 -3
- package/dist/{chunk-5GOMXHLC.js → chunk-KKTXCFD7.js} +255 -1
- package/dist/chunk-KKTXCFD7.js.map +1 -0
- package/dist/{chunk-FH3PPO42.js → chunk-KVFYTRMV.js} +2 -2
- package/dist/{chunk-BNW5NJJH.js → chunk-LQYTQCXM.js} +2 -2
- package/dist/{chunk-AYHXQR53.js → chunk-MVQN73GT.js} +2 -2
- package/dist/{chunk-ZZPIJPPD.js → chunk-N5RGXWLQ.js} +2 -2
- package/dist/chunk-NDAH7BJ5.js +213 -0
- package/dist/chunk-NDAH7BJ5.js.map +1 -0
- package/dist/{chunk-R3OQGYOU.js → chunk-P2D2MM47.js} +2 -2
- package/dist/{chunk-PSUB67YB.js → chunk-PW6GURU3.js} +2 -2
- package/dist/{chunk-W3BKVM64.js → chunk-QDV6VAD4.js} +2 -2
- package/dist/{chunk-3QSU4NFF.js → chunk-QHXW3LZV.js} +3 -3
- package/dist/{chunk-I6UCUHLK.js → chunk-SHV5Y2WU.js} +182 -3
- package/dist/chunk-SHV5Y2WU.js.map +1 -0
- package/dist/{chunk-OZXVGYGZ.js → chunk-STDAAGH7.js} +2 -2
- package/dist/{chunk-FMGWXIES.js → chunk-TZDSNIRO.js} +5 -5
- package/dist/{chunk-2L54V4ZO.js → chunk-UELS6WWF.js} +2 -2
- package/dist/{chunk-PJGB7XRR.js → chunk-UGHUNQ74.js} +502 -134
- package/dist/chunk-UGHUNQ74.js.map +1 -0
- package/dist/{chunk-FG76RDVI.js → chunk-Y3TMFC6I.js} +136 -4
- package/dist/chunk-Y3TMFC6I.js.map +1 -0
- package/dist/{chunk-BPSGLMQ4.js → chunk-YQNADJCT.js} +2 -2
- package/dist/{cli-Cw729yLf.d.ts → cli-EZv6YE6_.d.ts} +3 -3
- package/dist/cli.d.ts +6 -6
- package/dist/cli.js +23 -21
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +3 -3
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +2 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +3 -3
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +3 -3
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +3 -3
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +4 -4
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +307 -9
- package/dist/index.js +155 -29
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +3 -3
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +3 -3
- package/dist/maintenance/rebuild-memory-projection.js +4 -4
- package/dist/mcp-memory-inspector-app.d.ts +5 -5
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +1 -1
- package/dist/namespaces/migrate.js +4 -4
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +1 -1
- package/dist/namespaces/storage.js +3 -3
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +8 -7
- package/dist/{orchestrator-CqWOjfgl.d.ts → orchestrator-CEycaY3M.d.ts} +361 -4
- package/dist/orchestrator.d.ts +4 -4
- package/dist/orchestrator.js +13 -11
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +3 -2
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/schemas.d.ts +10 -10
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-SLAa_prH.d.ts → semantic-DJR8_DMQ.d.ts} +1 -1
- package/dist/{semantic-consolidation-4HkHWgeI.d.ts → semantic-consolidation-FbhPeJjB.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +4 -4
- package/dist/semantic-rule-promotion.js +3 -3
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +3 -3
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +5 -5
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +19 -1
- package/dist/storage.js +2 -2
- package/dist/summarizer.d.ts +1 -1
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/types-D5VRAI04.d.ts +3134 -0
- package/dist/types.d.ts +3 -2862
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +3 -3
- package/package.json +1 -1
- package/src/access-http.ts +167 -0
- package/src/access-mcp.ts +198 -0
- package/src/access-service.ts +65 -0
- package/src/cli.ts +187 -0
- package/src/config.ts +7 -0
- package/src/index.ts +7 -0
- package/src/orchestrator.ts +42 -0
- package/src/storage.ts +106 -0
- package/src/types.ts +5 -0
- package/src/wearables/cleanup.test.ts +134 -0
- package/src/wearables/cleanup.ts +188 -0
- package/src/wearables/cli.test.ts +170 -0
- package/src/wearables/cli.ts +441 -0
- package/src/wearables/config.test.ts +143 -0
- package/src/wearables/config.ts +332 -0
- package/src/wearables/corrections.test.ts +118 -0
- package/src/wearables/corrections.ts +211 -0
- package/src/wearables/day-store.test.ts +143 -0
- package/src/wearables/day-store.ts +238 -0
- package/src/wearables/errors.test.ts +32 -0
- package/src/wearables/errors.ts +29 -0
- package/src/wearables/index.ts +114 -0
- package/src/wearables/memory-gen.test.ts +342 -0
- package/src/wearables/memory-gen.ts +413 -0
- package/src/wearables/pipeline.test.ts +608 -0
- package/src/wearables/pipeline.ts +519 -0
- package/src/wearables/redaction.test.ts +94 -0
- package/src/wearables/redaction.ts +156 -0
- package/src/wearables/registry.test.ts +62 -0
- package/src/wearables/registry.ts +133 -0
- package/src/wearables/service.test.ts +425 -0
- package/src/wearables/service.ts +691 -0
- package/src/wearables/speakers.test.ts +110 -0
- package/src/wearables/speakers.ts +174 -0
- package/src/wearables/storage-io.test.ts +105 -0
- package/src/wearables/sync-state.test.ts +134 -0
- package/src/wearables/sync-state.ts +186 -0
- package/src/wearables/types.ts +285 -0
- package/dist/chunk-4R4KTDIE.js.map +0 -1
- package/dist/chunk-5GOMXHLC.js.map +0 -1
- package/dist/chunk-7TPH6UZL.js.map +0 -1
- package/dist/chunk-FG76RDVI.js.map +0 -1
- package/dist/chunk-I6UCUHLK.js.map +0 -1
- package/dist/chunk-KQFQ3IS5.js.map +0 -1
- package/dist/chunk-PJGB7XRR.js.map +0 -1
- package/dist/chunk-RKW6QR7W.js.map +0 -1
- /package/dist/{chunk-GYTVOLNX.js.map → chunk-3MNBW7R7.js.map} +0 -0
- /package/dist/{chunk-QFQQFX2H.js.map → chunk-3R2UZV3U.js.map} +0 -0
- /package/dist/{chunk-O4UNM6OR.js.map → chunk-532VCWYW.js.map} +0 -0
- /package/dist/{chunk-2UFQYU5F.js.map → chunk-57QXN2CS.js.map} +0 -0
- /package/dist/{chunk-UGEBPVNI.js.map → chunk-GE7Q7KXP.js.map} +0 -0
- /package/dist/{chunk-GLWW3EJQ.js.map → chunk-KB4MFBF5.js.map} +0 -0
- /package/dist/{chunk-FH3PPO42.js.map → chunk-KVFYTRMV.js.map} +0 -0
- /package/dist/{chunk-BNW5NJJH.js.map → chunk-LQYTQCXM.js.map} +0 -0
- /package/dist/{chunk-AYHXQR53.js.map → chunk-MVQN73GT.js.map} +0 -0
- /package/dist/{chunk-ZZPIJPPD.js.map → chunk-N5RGXWLQ.js.map} +0 -0
- /package/dist/{chunk-R3OQGYOU.js.map → chunk-P2D2MM47.js.map} +0 -0
- /package/dist/{chunk-PSUB67YB.js.map → chunk-PW6GURU3.js.map} +0 -0
- /package/dist/{chunk-W3BKVM64.js.map → chunk-QDV6VAD4.js.map} +0 -0
- /package/dist/{chunk-3QSU4NFF.js.map → chunk-QHXW3LZV.js.map} +0 -0
- /package/dist/{chunk-OZXVGYGZ.js.map → chunk-STDAAGH7.js.map} +0 -0
- /package/dist/{chunk-FMGWXIES.js.map → chunk-TZDSNIRO.js.map} +0 -0
- /package/dist/{chunk-2L54V4ZO.js.map → chunk-UELS6WWF.js.map} +0 -0
- /package/dist/{chunk-BPSGLMQ4.js.map → chunk-YQNADJCT.js.map} +0 -0
package/dist/types.js
CHANGED
package/dist/verified-recall.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
searchVerifiedEpisodes
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-P2D2MM47.js";
|
|
4
4
|
import "./chunk-HQ6NIBL6.js";
|
|
5
|
-
import "./chunk-
|
|
5
|
+
import "./chunk-UGHUNQ74.js";
|
|
6
6
|
import "./chunk-5UZXUTVO.js";
|
|
7
7
|
import "./chunk-J6A3CX5N.js";
|
|
8
|
-
import "./chunk-
|
|
8
|
+
import "./chunk-FPNQF475.js";
|
|
9
9
|
import "./chunk-RULE4VG5.js";
|
|
10
10
|
import "./chunk-SCU65EZI.js";
|
|
11
11
|
import "./chunk-MB5RSUW6.js";
|
package/package.json
CHANGED
package/src/access-http.ts
CHANGED
|
@@ -8,6 +8,7 @@ import { fileURLToPath, URL } from "node:url";
|
|
|
8
8
|
import { gunzipSync } from "node:zlib";
|
|
9
9
|
import { log } from "./logger.js";
|
|
10
10
|
import { EngramAccessInputError, type EngramAccessService } from "./access-service.js";
|
|
11
|
+
import { WearablesInputError } from "./wearables/errors.js";
|
|
11
12
|
import { EngramMcpServer } from "./access-mcp.js";
|
|
12
13
|
import { validateRequest, type SchemaName, type SchemaTypeFor } from "./access-schema.js";
|
|
13
14
|
import {
|
|
@@ -1005,6 +1006,128 @@ export class EngramAccessHttpServer {
|
|
|
1005
1006
|
return;
|
|
1006
1007
|
}
|
|
1007
1008
|
|
|
1009
|
+
// -- Wearables (Limitless / Bee / Omi transcript ingestion). All
|
|
1010
|
+
// behavior + validation lives in WearablesService; these routes
|
|
1011
|
+
// translate transport shape only. Service validation errors map
|
|
1012
|
+
// to 400 via respondWearablesError; backend faults bubble to the
|
|
1013
|
+
// global 500 handler.
|
|
1014
|
+
if (
|
|
1015
|
+
req.method === "GET" &&
|
|
1016
|
+
(pathname === "/engram/v1/wearables/status" || pathname === "/remnic/v1/wearables/status")
|
|
1017
|
+
) {
|
|
1018
|
+
this.respondJson(res, 200, await this.service.wearablesStatus());
|
|
1019
|
+
return;
|
|
1020
|
+
}
|
|
1021
|
+
|
|
1022
|
+
if (
|
|
1023
|
+
req.method === "POST" &&
|
|
1024
|
+
(pathname === "/engram/v1/wearables/sync" || pathname === "/remnic/v1/wearables/sync")
|
|
1025
|
+
) {
|
|
1026
|
+
const body = (await this.readJsonBody(req)) as Record<string, unknown>;
|
|
1027
|
+
const source = optionalQueryString(body.source, "source");
|
|
1028
|
+
const date = optionalQueryString(body.date, "date");
|
|
1029
|
+
let days: number | undefined;
|
|
1030
|
+
if (body.days !== undefined && body.days !== null) {
|
|
1031
|
+
if (
|
|
1032
|
+
typeof body.days !== "number" ||
|
|
1033
|
+
!Number.isInteger(body.days) ||
|
|
1034
|
+
body.days < 1
|
|
1035
|
+
) {
|
|
1036
|
+
throw new EngramAccessInputError(
|
|
1037
|
+
`days must be a positive integer (got ${JSON.stringify(body.days)})`,
|
|
1038
|
+
);
|
|
1039
|
+
}
|
|
1040
|
+
days = body.days;
|
|
1041
|
+
}
|
|
1042
|
+
if (body.forceMemories !== undefined && typeof body.forceMemories !== "boolean") {
|
|
1043
|
+
throw new EngramAccessInputError(
|
|
1044
|
+
`forceMemories must be a boolean (got ${JSON.stringify(body.forceMemories)})`,
|
|
1045
|
+
);
|
|
1046
|
+
}
|
|
1047
|
+
try {
|
|
1048
|
+
const summaries = await this.service.wearablesSync({
|
|
1049
|
+
source,
|
|
1050
|
+
date,
|
|
1051
|
+
days,
|
|
1052
|
+
forceMemories: body.forceMemories === true,
|
|
1053
|
+
});
|
|
1054
|
+
this.respondJson(res, 200, { summaries });
|
|
1055
|
+
} catch (err) {
|
|
1056
|
+
if (this.respondWearablesError(res, err)) return;
|
|
1057
|
+
throw err;
|
|
1058
|
+
}
|
|
1059
|
+
return;
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
if (
|
|
1063
|
+
req.method === "GET" &&
|
|
1064
|
+
(pathname === "/engram/v1/wearables/transcript" || pathname === "/remnic/v1/wearables/transcript")
|
|
1065
|
+
) {
|
|
1066
|
+
const date = parsed.searchParams.get("date");
|
|
1067
|
+
if (!date || date.trim().length === 0) {
|
|
1068
|
+
throw new EngramAccessInputError(
|
|
1069
|
+
"date query parameter is required (YYYY-MM-DD)",
|
|
1070
|
+
);
|
|
1071
|
+
}
|
|
1072
|
+
const sourceParam = parsed.searchParams.get("source");
|
|
1073
|
+
try {
|
|
1074
|
+
const transcripts = await this.service.wearablesTranscriptDay({
|
|
1075
|
+
date,
|
|
1076
|
+
source: sourceParam && sourceParam.length > 0 ? sourceParam : undefined,
|
|
1077
|
+
});
|
|
1078
|
+
this.respondJson(res, 200, { transcripts });
|
|
1079
|
+
} catch (err) {
|
|
1080
|
+
if (this.respondWearablesError(res, err)) return;
|
|
1081
|
+
throw err;
|
|
1082
|
+
}
|
|
1083
|
+
return;
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
if (
|
|
1087
|
+
req.method === "GET" &&
|
|
1088
|
+
(pathname === "/engram/v1/wearables/transcripts/search" ||
|
|
1089
|
+
pathname === "/remnic/v1/wearables/transcripts/search")
|
|
1090
|
+
) {
|
|
1091
|
+
const queryParam = parsed.searchParams.get("q");
|
|
1092
|
+
if (!queryParam || queryParam.trim().length === 0) {
|
|
1093
|
+
throw new EngramAccessInputError(
|
|
1094
|
+
"q query parameter is required and must be non-empty",
|
|
1095
|
+
);
|
|
1096
|
+
}
|
|
1097
|
+
try {
|
|
1098
|
+
const results = await this.service.wearablesTranscriptSearch({
|
|
1099
|
+
query: queryParam,
|
|
1100
|
+
source: nonEmptyQueryParam(parsed.searchParams.get("source")),
|
|
1101
|
+
from: nonEmptyQueryParam(parsed.searchParams.get("from")),
|
|
1102
|
+
to: nonEmptyQueryParam(parsed.searchParams.get("to")),
|
|
1103
|
+
limit: positiveIntQueryParam(parsed.searchParams.get("limit"), "limit"),
|
|
1104
|
+
});
|
|
1105
|
+
this.respondJson(res, 200, { results });
|
|
1106
|
+
} catch (err) {
|
|
1107
|
+
if (this.respondWearablesError(res, err)) return;
|
|
1108
|
+
throw err;
|
|
1109
|
+
}
|
|
1110
|
+
return;
|
|
1111
|
+
}
|
|
1112
|
+
|
|
1113
|
+
if (
|
|
1114
|
+
req.method === "GET" &&
|
|
1115
|
+
(pathname === "/engram/v1/wearables/memories" || pathname === "/remnic/v1/wearables/memories")
|
|
1116
|
+
) {
|
|
1117
|
+
try {
|
|
1118
|
+
const memories = await this.service.wearablesTranscriptMemories({
|
|
1119
|
+
source: nonEmptyQueryParam(parsed.searchParams.get("source")),
|
|
1120
|
+
date: nonEmptyQueryParam(parsed.searchParams.get("date")),
|
|
1121
|
+
limit: positiveIntQueryParam(parsed.searchParams.get("limit"), "limit"),
|
|
1122
|
+
});
|
|
1123
|
+
this.respondJson(res, 200, { memories });
|
|
1124
|
+
} catch (err) {
|
|
1125
|
+
if (this.respondWearablesError(res, err)) return;
|
|
1126
|
+
throw err;
|
|
1127
|
+
}
|
|
1128
|
+
return;
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1008
1131
|
if (req.method === "POST" && pathname === "/engram/v1/observe") {
|
|
1009
1132
|
const body = await this.readValidatedBody(req, "observe");
|
|
1010
1133
|
this.ensureWriteRateLimitAvailable();
|
|
@@ -2372,4 +2495,48 @@ export class EngramAccessHttpServer {
|
|
|
2372
2495
|
private shouldCountWriteRateLimit(response: { dryRun?: boolean; idempotencyReplay?: boolean }): boolean {
|
|
2373
2496
|
return response.dryRun !== true && response.idempotencyReplay !== true;
|
|
2374
2497
|
}
|
|
2498
|
+
|
|
2499
|
+
/**
|
|
2500
|
+
* Map wearables validation errors (WearablesInputError — invalid
|
|
2501
|
+
* params, unknown/disabled sources, missing connector packages) to a
|
|
2502
|
+
* 400 response. Returns false for everything else so backend faults
|
|
2503
|
+
* keep flowing to the global 500 handler.
|
|
2504
|
+
*/
|
|
2505
|
+
private respondWearablesError(res: ServerResponse, err: unknown): boolean {
|
|
2506
|
+
if (err instanceof WearablesInputError) {
|
|
2507
|
+
this.respondJson(res, 400, {
|
|
2508
|
+
error: "invalid_request",
|
|
2509
|
+
code: "invalid_request",
|
|
2510
|
+
message: err.message,
|
|
2511
|
+
});
|
|
2512
|
+
return true;
|
|
2513
|
+
}
|
|
2514
|
+
return false;
|
|
2515
|
+
}
|
|
2516
|
+
}
|
|
2517
|
+
|
|
2518
|
+
/** Optional string field from a JSON body: absent/null/"" → undefined. */
|
|
2519
|
+
function optionalQueryString(value: unknown, label: string): string | undefined {
|
|
2520
|
+
if (value === undefined || value === null || value === "") return undefined;
|
|
2521
|
+
if (typeof value !== "string") {
|
|
2522
|
+
throw new EngramAccessInputError(
|
|
2523
|
+
`${label} must be a string (got ${JSON.stringify(value)})`,
|
|
2524
|
+
);
|
|
2525
|
+
}
|
|
2526
|
+
return value;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2529
|
+
/** Optional non-empty query param: null/"" → undefined. */
|
|
2530
|
+
function nonEmptyQueryParam(value: string | null): string | undefined {
|
|
2531
|
+
return value !== null && value.length > 0 ? value : undefined;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
/** Optional positive-integer query param; rejects invalid values. */
|
|
2535
|
+
function positiveIntQueryParam(value: string | null, label: string): number | undefined {
|
|
2536
|
+
if (value === null || value.length === 0) return undefined;
|
|
2537
|
+
const parsed = Number(value);
|
|
2538
|
+
if (!Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
|
|
2539
|
+
throw new EngramAccessInputError(`${label} expects a positive integer`);
|
|
2540
|
+
}
|
|
2541
|
+
return parsed;
|
|
2375
2542
|
}
|
package/src/access-mcp.ts
CHANGED
|
@@ -204,6 +204,36 @@ function parseMcpRequest<N extends SchemaName>(
|
|
|
204
204
|
);
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Strict optional-string MCP argument: absent/null/"" → undefined,
|
|
209
|
+
* non-string → loud error (CLAUDE.md rule 51 — no silent coercion).
|
|
210
|
+
*/
|
|
211
|
+
function optionalNonEmptyString(value: unknown, label: string): string | undefined {
|
|
212
|
+
if (value === undefined || value === null || value === "") return undefined;
|
|
213
|
+
if (typeof value !== "string") {
|
|
214
|
+
throw new Error(`${label} expects a string; got ${JSON.stringify(value)}`);
|
|
215
|
+
}
|
|
216
|
+
return value;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Strict optional positive-integer MCP argument. Accepts JSON numbers
|
|
221
|
+
* and numeric strings (loosely-typed MCP clients send both); rejects
|
|
222
|
+
* everything else including booleans, which `Number()` would silently
|
|
223
|
+
* coerce.
|
|
224
|
+
*/
|
|
225
|
+
function optionalPositiveInteger(value: unknown, label: string): number | undefined {
|
|
226
|
+
if (value === undefined || value === null || value === "") return undefined;
|
|
227
|
+
if (typeof value !== "number" && typeof value !== "string") {
|
|
228
|
+
throw new Error(`${label} expects a positive integer; got ${JSON.stringify(value)}`);
|
|
229
|
+
}
|
|
230
|
+
const parsed = typeof value === "number" ? value : Number(value);
|
|
231
|
+
if (!Number.isFinite(parsed) || parsed <= 0 || !Number.isInteger(parsed)) {
|
|
232
|
+
throw new Error(`${label} expects a positive integer; got ${JSON.stringify(value)}`);
|
|
233
|
+
}
|
|
234
|
+
return parsed;
|
|
235
|
+
}
|
|
236
|
+
|
|
207
237
|
function getObjectProperties(value: unknown): Record<string, unknown> | undefined {
|
|
208
238
|
return value && typeof value === "object" && !Array.isArray(value)
|
|
209
239
|
? (value as Record<string, unknown>)
|
|
@@ -452,6 +482,124 @@ export class EngramMcpServer {
|
|
|
452
482
|
additionalProperties: false,
|
|
453
483
|
},
|
|
454
484
|
},
|
|
485
|
+
{
|
|
486
|
+
name: "engram.wearables_status",
|
|
487
|
+
description:
|
|
488
|
+
"Status of wearable transcript sources (Limitless / Bee / Omi): configured sources, connector availability, last sync, stored transcript days.",
|
|
489
|
+
inputSchema: {
|
|
490
|
+
type: "object",
|
|
491
|
+
properties: {},
|
|
492
|
+
additionalProperties: false,
|
|
493
|
+
},
|
|
494
|
+
},
|
|
495
|
+
{
|
|
496
|
+
name: "engram.wearables_sync",
|
|
497
|
+
description:
|
|
498
|
+
"Pull, clean, and store wearable transcripts for one source or all enabled sources; optionally creates trust-gated memories per the source's memoryMode.",
|
|
499
|
+
inputSchema: {
|
|
500
|
+
type: "object",
|
|
501
|
+
properties: {
|
|
502
|
+
source: {
|
|
503
|
+
type: "string",
|
|
504
|
+
description: "Source id (e.g. limitless, bee, omi). Omit to sync every enabled source.",
|
|
505
|
+
},
|
|
506
|
+
date: {
|
|
507
|
+
type: "string",
|
|
508
|
+
description: "Sync exactly this day (YYYY-MM-DD). Overrides days.",
|
|
509
|
+
},
|
|
510
|
+
days: {
|
|
511
|
+
type: "integer",
|
|
512
|
+
minimum: 1,
|
|
513
|
+
maximum: 90,
|
|
514
|
+
description: "Lookback window in days ending today (default 2).",
|
|
515
|
+
},
|
|
516
|
+
forceMemories: {
|
|
517
|
+
type: "boolean",
|
|
518
|
+
description: "Re-run memory extraction even for unchanged days.",
|
|
519
|
+
},
|
|
520
|
+
},
|
|
521
|
+
additionalProperties: false,
|
|
522
|
+
},
|
|
523
|
+
},
|
|
524
|
+
{
|
|
525
|
+
name: "engram.transcript_day",
|
|
526
|
+
description:
|
|
527
|
+
"Return the full stored wearable transcript(s) for a day, across all sources or one source, with cross-source overlap hints.",
|
|
528
|
+
inputSchema: {
|
|
529
|
+
type: "object",
|
|
530
|
+
properties: {
|
|
531
|
+
date: {
|
|
532
|
+
type: "string",
|
|
533
|
+
description: "Day to read (YYYY-MM-DD). Required.",
|
|
534
|
+
},
|
|
535
|
+
source: {
|
|
536
|
+
type: "string",
|
|
537
|
+
description: "Optional source id to scope to (e.g. limitless).",
|
|
538
|
+
},
|
|
539
|
+
},
|
|
540
|
+
required: ["date"],
|
|
541
|
+
additionalProperties: false,
|
|
542
|
+
},
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
name: "engram.transcript_search",
|
|
546
|
+
description:
|
|
547
|
+
"Search stored wearable transcripts. Results carry source + date so callers can pull the full day via engram.transcript_day.",
|
|
548
|
+
inputSchema: {
|
|
549
|
+
type: "object",
|
|
550
|
+
properties: {
|
|
551
|
+
query: {
|
|
552
|
+
type: "string",
|
|
553
|
+
description: "Search query. Required; non-empty.",
|
|
554
|
+
},
|
|
555
|
+
source: {
|
|
556
|
+
type: "string",
|
|
557
|
+
description: "Optional source id filter.",
|
|
558
|
+
},
|
|
559
|
+
from: {
|
|
560
|
+
type: "string",
|
|
561
|
+
description: "Optional inclusive start date (YYYY-MM-DD).",
|
|
562
|
+
},
|
|
563
|
+
to: {
|
|
564
|
+
type: "string",
|
|
565
|
+
description: "Optional inclusive end date (YYYY-MM-DD).",
|
|
566
|
+
},
|
|
567
|
+
limit: {
|
|
568
|
+
type: "integer",
|
|
569
|
+
minimum: 1,
|
|
570
|
+
maximum: 50,
|
|
571
|
+
description: "Maximum results (default 10).",
|
|
572
|
+
},
|
|
573
|
+
},
|
|
574
|
+
required: ["query"],
|
|
575
|
+
additionalProperties: false,
|
|
576
|
+
},
|
|
577
|
+
},
|
|
578
|
+
{
|
|
579
|
+
name: "engram.transcript_memories",
|
|
580
|
+
description:
|
|
581
|
+
"List memories created from wearable transcripts, filterable by source and/or day. Includes pending_review candidates awaiting approval.",
|
|
582
|
+
inputSchema: {
|
|
583
|
+
type: "object",
|
|
584
|
+
properties: {
|
|
585
|
+
source: {
|
|
586
|
+
type: "string",
|
|
587
|
+
description: "Optional source id filter (e.g. limitless).",
|
|
588
|
+
},
|
|
589
|
+
date: {
|
|
590
|
+
type: "string",
|
|
591
|
+
description: "Optional transcript day filter (YYYY-MM-DD).",
|
|
592
|
+
},
|
|
593
|
+
limit: {
|
|
594
|
+
type: "integer",
|
|
595
|
+
minimum: 1,
|
|
596
|
+
maximum: 200,
|
|
597
|
+
description: "Maximum results (default 50).",
|
|
598
|
+
},
|
|
599
|
+
},
|
|
600
|
+
additionalProperties: false,
|
|
601
|
+
},
|
|
602
|
+
},
|
|
455
603
|
{
|
|
456
604
|
name: "engram.action_confidence",
|
|
457
605
|
description:
|
|
@@ -2348,6 +2496,56 @@ export class EngramMcpServer {
|
|
|
2348
2496
|
: {}),
|
|
2349
2497
|
});
|
|
2350
2498
|
}
|
|
2499
|
+
case "engram.wearables_status":
|
|
2500
|
+
return this.service.wearablesStatus();
|
|
2501
|
+
case "engram.wearables_sync": {
|
|
2502
|
+
const source = optionalNonEmptyString(args.source, "engram.wearables_sync: source");
|
|
2503
|
+
const date = optionalNonEmptyString(args.date, "engram.wearables_sync: date");
|
|
2504
|
+
const days = optionalPositiveInteger(args.days, "engram.wearables_sync: days");
|
|
2505
|
+
let forceMemories: boolean | undefined;
|
|
2506
|
+
if (args.forceMemories !== undefined && args.forceMemories !== null) {
|
|
2507
|
+
if (typeof args.forceMemories !== "boolean") {
|
|
2508
|
+
throw new Error(
|
|
2509
|
+
`engram.wearables_sync: forceMemories expects a boolean; got ${JSON.stringify(args.forceMemories)}`,
|
|
2510
|
+
);
|
|
2511
|
+
}
|
|
2512
|
+
forceMemories = args.forceMemories;
|
|
2513
|
+
}
|
|
2514
|
+
// Date/days/source validation beyond shape lives in the shared
|
|
2515
|
+
// WearablesService so CLI/HTTP/MCP reject identically.
|
|
2516
|
+
return this.service.wearablesSync({ source, date, days, forceMemories });
|
|
2517
|
+
}
|
|
2518
|
+
case "engram.transcript_day": {
|
|
2519
|
+
const date = typeof args.date === "string" ? args.date : "";
|
|
2520
|
+
if (date.trim().length === 0) {
|
|
2521
|
+
throw new Error(
|
|
2522
|
+
"engram.transcript_day: date is required and must be YYYY-MM-DD",
|
|
2523
|
+
);
|
|
2524
|
+
}
|
|
2525
|
+
const source = optionalNonEmptyString(args.source, "engram.transcript_day: source");
|
|
2526
|
+
return this.service.wearablesTranscriptDay({ date, source });
|
|
2527
|
+
}
|
|
2528
|
+
case "engram.transcript_search": {
|
|
2529
|
+
const query = typeof args.query === "string" ? args.query : "";
|
|
2530
|
+
if (query.trim().length === 0) {
|
|
2531
|
+
throw new Error(
|
|
2532
|
+
"engram.transcript_search: query is required and must be non-empty",
|
|
2533
|
+
);
|
|
2534
|
+
}
|
|
2535
|
+
return this.service.wearablesTranscriptSearch({
|
|
2536
|
+
query,
|
|
2537
|
+
source: optionalNonEmptyString(args.source, "engram.transcript_search: source"),
|
|
2538
|
+
from: optionalNonEmptyString(args.from, "engram.transcript_search: from"),
|
|
2539
|
+
to: optionalNonEmptyString(args.to, "engram.transcript_search: to"),
|
|
2540
|
+
limit: optionalPositiveInteger(args.limit, "engram.transcript_search: limit"),
|
|
2541
|
+
});
|
|
2542
|
+
}
|
|
2543
|
+
case "engram.transcript_memories":
|
|
2544
|
+
return this.service.wearablesTranscriptMemories({
|
|
2545
|
+
source: optionalNonEmptyString(args.source, "engram.transcript_memories: source"),
|
|
2546
|
+
date: optionalNonEmptyString(args.date, "engram.transcript_memories: date"),
|
|
2547
|
+
limit: optionalPositiveInteger(args.limit, "engram.transcript_memories: limit"),
|
|
2548
|
+
});
|
|
2351
2549
|
case "engram.action_confidence": {
|
|
2352
2550
|
const body: ActionConfidenceRequest = parseMcpRequest("actionConfidence", args);
|
|
2353
2551
|
return this.service.actionConfidence(body);
|
package/src/access-service.ts
CHANGED
|
@@ -39,6 +39,7 @@ import {
|
|
|
39
39
|
import { runProcedureMining } from "./procedural/procedure-miner.js";
|
|
40
40
|
import type { PatternReinforcementResult } from "./maintenance/pattern-reinforcement.js";
|
|
41
41
|
import type { LiveConnectorsRunSummary } from "./live-connectors-runner.js";
|
|
42
|
+
import type { WearablesService } from "./wearables/service.js";
|
|
42
43
|
import {
|
|
43
44
|
computeProcedureStats,
|
|
44
45
|
type ProcedureStatsReport,
|
|
@@ -6154,4 +6155,68 @@ export class EngramAccessService {
|
|
|
6154
6155
|
notes: result.notes,
|
|
6155
6156
|
};
|
|
6156
6157
|
}
|
|
6158
|
+
|
|
6159
|
+
// ---------------------------------------------------------------------------
|
|
6160
|
+
// Wearables (Limitless / Bee / Omi transcript ingestion)
|
|
6161
|
+
//
|
|
6162
|
+
// Thin delegations to the orchestrator-owned WearablesService — the
|
|
6163
|
+
// same instance behind the CLI, so HTTP/MCP callers observe identical
|
|
6164
|
+
// behavior and validation (renderer-sharing rule).
|
|
6165
|
+
// ---------------------------------------------------------------------------
|
|
6166
|
+
|
|
6167
|
+
async wearablesStatus(): Promise<
|
|
6168
|
+
Awaited<ReturnType<WearablesService["status"]>>
|
|
6169
|
+
> {
|
|
6170
|
+
return this.orchestrator.getWearablesService().status();
|
|
6171
|
+
}
|
|
6172
|
+
|
|
6173
|
+
async wearablesSync(request: {
|
|
6174
|
+
source?: string;
|
|
6175
|
+
date?: string;
|
|
6176
|
+
days?: number;
|
|
6177
|
+
forceMemories?: boolean;
|
|
6178
|
+
}): Promise<Awaited<ReturnType<WearablesService["sync"]>>> {
|
|
6179
|
+
return this.orchestrator.getWearablesService().sync({
|
|
6180
|
+
source: request.source,
|
|
6181
|
+
date: request.date,
|
|
6182
|
+
days: request.days,
|
|
6183
|
+
forceMemories: request.forceMemories,
|
|
6184
|
+
});
|
|
6185
|
+
}
|
|
6186
|
+
|
|
6187
|
+
async wearablesTranscriptDay(request: {
|
|
6188
|
+
date: string;
|
|
6189
|
+
source?: string;
|
|
6190
|
+
}): Promise<Awaited<ReturnType<WearablesService["dayTranscript"]>>> {
|
|
6191
|
+
return this.orchestrator
|
|
6192
|
+
.getWearablesService()
|
|
6193
|
+
.dayTranscript(request.date, request.source);
|
|
6194
|
+
}
|
|
6195
|
+
|
|
6196
|
+
async wearablesTranscriptSearch(request: {
|
|
6197
|
+
query: string;
|
|
6198
|
+
source?: string;
|
|
6199
|
+
from?: string;
|
|
6200
|
+
to?: string;
|
|
6201
|
+
limit?: number;
|
|
6202
|
+
}): Promise<Awaited<ReturnType<WearablesService["searchTranscripts"]>>> {
|
|
6203
|
+
return this.orchestrator.getWearablesService().searchTranscripts(request.query, {
|
|
6204
|
+
source: request.source,
|
|
6205
|
+
from: request.from,
|
|
6206
|
+
to: request.to,
|
|
6207
|
+
limit: request.limit,
|
|
6208
|
+
});
|
|
6209
|
+
}
|
|
6210
|
+
|
|
6211
|
+
async wearablesTranscriptMemories(request: {
|
|
6212
|
+
source?: string;
|
|
6213
|
+
date?: string;
|
|
6214
|
+
limit?: number;
|
|
6215
|
+
}): Promise<Awaited<ReturnType<WearablesService["transcriptMemories"]>>> {
|
|
6216
|
+
return this.orchestrator.getWearablesService().transcriptMemories({
|
|
6217
|
+
source: request.source,
|
|
6218
|
+
date: request.date,
|
|
6219
|
+
limit: request.limit,
|
|
6220
|
+
});
|
|
6221
|
+
}
|
|
6157
6222
|
}
|