@gamaze/hicortex 0.14.3 → 0.14.4
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/mcp-server.js +17 -0
- package/dist/memory-instructions.d.ts +38 -0
- package/dist/memory-instructions.js +63 -0
- package/package.json +1 -1
package/dist/mcp-server.js
CHANGED
|
@@ -65,6 +65,7 @@ const viz_js_1 = require("./viz.js");
|
|
|
65
65
|
const context_store_js_1 = require("./context-store.js");
|
|
66
66
|
const retrieval = __importStar(require("./retrieval.js"));
|
|
67
67
|
const recall_registry_js_1 = require("./recall-registry.js");
|
|
68
|
+
const memory_instructions_js_1 = require("./memory-instructions.js");
|
|
68
69
|
const recall_index_js_1 = require("./recall-index.js");
|
|
69
70
|
const seed_lesson_js_1 = require("./seed-lesson.js");
|
|
70
71
|
const distiller_js_1 = require("./distiller.js");
|
|
@@ -90,6 +91,8 @@ let contextAgents = {};
|
|
|
90
91
|
// Pushed-recall dedup registry (#192) + options; configured at boot.
|
|
91
92
|
let recallRegistry = new recall_registry_js_1.SessionRecallRegistry();
|
|
92
93
|
let recallIndexOptions = {};
|
|
94
|
+
// Product-owned memory instructions (#192): on unless config says false.
|
|
95
|
+
let memoryInstructionsEnabled = true;
|
|
93
96
|
// Cache detectChunkSize results keyed by "<provider>/<model>@<baseUrl>" so we
|
|
94
97
|
// probe each endpoint once per server boot rather than once per /distill request.
|
|
95
98
|
const chunkSizeCache = new Map();
|
|
@@ -493,6 +496,7 @@ async function startServer(options = {}) {
|
|
|
493
496
|
maxItems: savedConfig?.recallMaxItems,
|
|
494
497
|
minPromptLength: savedConfig?.recallMinPromptChars,
|
|
495
498
|
};
|
|
499
|
+
memoryInstructionsEnabled = savedConfig?.memoryInstructions !== false;
|
|
496
500
|
if (resolvedAgents.dropped.length > 0) {
|
|
497
501
|
console.warn(`[hicortex] Ignoring invalid contextAgents entries: ${resolvedAgents.dropped.join(", ")} ` +
|
|
498
502
|
`(keys must match ^[a-z0-9][a-z0-9_-]*$; modes must be override|global|off)`);
|
|
@@ -727,6 +731,13 @@ async function startServer(options = {}) {
|
|
|
727
731
|
app.get("/context", (req, res) => {
|
|
728
732
|
try {
|
|
729
733
|
const r = (0, context_store_js_1.handleContextGet)((0, node_path_1.join)(stateDir, "context"), contextClients, req.query, contextAgents);
|
|
734
|
+
// #192: product-owned memory instructions ride as a synthetic read-only
|
|
735
|
+
// `memory` section (config memoryInstructions !== false; agent mode
|
|
736
|
+
// "off" respected inside the helper). Every harness renders it via the
|
|
737
|
+
// shared section renderer — zero client changes.
|
|
738
|
+
if (r.status === 200) {
|
|
739
|
+
(0, memory_instructions_js_1.injectMemorySection)(r.body, memoryInstructionsEnabled);
|
|
740
|
+
}
|
|
730
741
|
res.status(r.status).json(r.body);
|
|
731
742
|
}
|
|
732
743
|
catch (err) {
|
|
@@ -735,6 +746,12 @@ async function startServer(options = {}) {
|
|
|
735
746
|
});
|
|
736
747
|
app.put("/context", (req, res) => {
|
|
737
748
|
try {
|
|
749
|
+
// Reserved product section: never writable, loud error (no silent skip).
|
|
750
|
+
const putSections = req.body?.sections;
|
|
751
|
+
if (putSections && Object.keys(putSections).some((n) => (0, memory_instructions_js_1.isReservedSectionName)(n))) {
|
|
752
|
+
res.status(400).json({ error: `Section name '${memory_instructions_js_1.MEMORY_SECTION_NAME}' is reserved for the product-owned memory instructions (config memoryInstructions to disable them)` });
|
|
753
|
+
return;
|
|
754
|
+
}
|
|
738
755
|
const r = (0, context_store_js_1.handleContextPut)((0, node_path_1.join)(stateDir, "context"), req.body, req.query, contextAgents);
|
|
739
756
|
if (r.warn)
|
|
740
757
|
console.warn(`[hicortex] ${r.warn}`);
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product-owned memory instructions (#192, owner decision 28.07.2026).
|
|
3
|
+
*
|
|
4
|
+
* The instructions for HOW agents use Hicortex are shipped BY the product,
|
|
5
|
+
* versioned with the server, and injected as a synthetic read-only `memory`
|
|
6
|
+
* section in the GET /context response. Rationale ("enforced, built-in"):
|
|
7
|
+
* - Harness personas (SOUL.md etc.) carry ZERO hicortex content — mechanics
|
|
8
|
+
* described there rot silently when the product changes (field evidence:
|
|
9
|
+
* stale "captured via hooks" sentences; an agent shell-spelunking its own
|
|
10
|
+
* plugin infrastructure when told "the plugin was updated").
|
|
11
|
+
* - User context files (user.md / rules.md) stay purely personal — norms the
|
|
12
|
+
* product depends on must not live in user-editable files (same principle
|
|
13
|
+
* as the built-in citation norm, 0.14.1).
|
|
14
|
+
* - Because every harness already renders `## Context` sections through the
|
|
15
|
+
* shared gate/render path, a synthetic section ships fleet-wide with zero
|
|
16
|
+
* client changes — including plugins that predate this feature.
|
|
17
|
+
*
|
|
18
|
+
* The section name is RESERVED: PUT /context rejects it, and the synthetic
|
|
19
|
+
* text overrides any user file of the same name (enforced means enforced).
|
|
20
|
+
* Off-switch: config `memoryInstructions: false`.
|
|
21
|
+
*/
|
|
22
|
+
export declare const MEMORY_SECTION_NAME = "memory";
|
|
23
|
+
/** The product-authored instruction text. Keep compact (~120 tokens): it is
|
|
24
|
+
* injected once per session into every agent on the fleet. */
|
|
25
|
+
export declare function renderMemoryInstructions(): string;
|
|
26
|
+
/** True for the reserved product section name (case-insensitive guard —
|
|
27
|
+
* section names are lowercase by allowlist, but be safe). */
|
|
28
|
+
export declare function isReservedSectionName(name: unknown): boolean;
|
|
29
|
+
/**
|
|
30
|
+
* Inject the synthetic section into a successful GET /context body.
|
|
31
|
+
* Pure: returns the same body object with sections.memory set. Skips agent
|
|
32
|
+
* mode "off" (operator explicitly silenced context for that agent) and
|
|
33
|
+
* non-object bodies (error shapes). Overrides a user file named memory.md.
|
|
34
|
+
*/
|
|
35
|
+
export declare function injectMemorySection<T extends {
|
|
36
|
+
sections?: Record<string, string>;
|
|
37
|
+
mode?: string;
|
|
38
|
+
}>(body: T, enabled: boolean): T;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Product-owned memory instructions (#192, owner decision 28.07.2026).
|
|
4
|
+
*
|
|
5
|
+
* The instructions for HOW agents use Hicortex are shipped BY the product,
|
|
6
|
+
* versioned with the server, and injected as a synthetic read-only `memory`
|
|
7
|
+
* section in the GET /context response. Rationale ("enforced, built-in"):
|
|
8
|
+
* - Harness personas (SOUL.md etc.) carry ZERO hicortex content — mechanics
|
|
9
|
+
* described there rot silently when the product changes (field evidence:
|
|
10
|
+
* stale "captured via hooks" sentences; an agent shell-spelunking its own
|
|
11
|
+
* plugin infrastructure when told "the plugin was updated").
|
|
12
|
+
* - User context files (user.md / rules.md) stay purely personal — norms the
|
|
13
|
+
* product depends on must not live in user-editable files (same principle
|
|
14
|
+
* as the built-in citation norm, 0.14.1).
|
|
15
|
+
* - Because every harness already renders `## Context` sections through the
|
|
16
|
+
* shared gate/render path, a synthetic section ships fleet-wide with zero
|
|
17
|
+
* client changes — including plugins that predate this feature.
|
|
18
|
+
*
|
|
19
|
+
* The section name is RESERVED: PUT /context rejects it, and the synthetic
|
|
20
|
+
* text overrides any user file of the same name (enforced means enforced).
|
|
21
|
+
* Off-switch: config `memoryInstructions: false`.
|
|
22
|
+
*/
|
|
23
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
+
exports.MEMORY_SECTION_NAME = void 0;
|
|
25
|
+
exports.renderMemoryInstructions = renderMemoryInstructions;
|
|
26
|
+
exports.isReservedSectionName = isReservedSectionName;
|
|
27
|
+
exports.injectMemorySection = injectMemorySection;
|
|
28
|
+
exports.MEMORY_SECTION_NAME = "memory";
|
|
29
|
+
/** The product-authored instruction text. Keep compact (~120 tokens): it is
|
|
30
|
+
* injected once per session into every agent on the fleet. */
|
|
31
|
+
function renderMemoryInstructions() {
|
|
32
|
+
return [
|
|
33
|
+
"Your long-term memory is Hicortex — shared across all agents and sessions.",
|
|
34
|
+
"- A `## Memory recall (auto)` index may arrive with prompts: it is a MENU, not content. Fetch a full memory with `hicortex_get(id)` only when the entry is relevant to your current task.",
|
|
35
|
+
"- Recall before assuming: `hicortex_search` for prior decisions/facts/preferences, `hicortex_recent` to catch up on a project.",
|
|
36
|
+
"- Cite any memory you rely on (id, date); on conflicts, newer memories supersede older.",
|
|
37
|
+
"- Capture is automatic (nightly). Do not manually ingest routine content — `hicortex_ingest` is for explicitly requested learnings only.",
|
|
38
|
+
"- Never inspect, test, or modify memory/plugin/gateway infrastructure (configs, services, tokens). If a memory tool seems missing or broken, say so and stop.",
|
|
39
|
+
].join("\n");
|
|
40
|
+
}
|
|
41
|
+
/** True for the reserved product section name (case-insensitive guard —
|
|
42
|
+
* section names are lowercase by allowlist, but be safe). */
|
|
43
|
+
function isReservedSectionName(name) {
|
|
44
|
+
return typeof name === "string" && name.trim().toLowerCase() === exports.MEMORY_SECTION_NAME;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Inject the synthetic section into a successful GET /context body.
|
|
48
|
+
* Pure: returns the same body object with sections.memory set. Skips agent
|
|
49
|
+
* mode "off" (operator explicitly silenced context for that agent) and
|
|
50
|
+
* non-object bodies (error shapes). Overrides a user file named memory.md.
|
|
51
|
+
*/
|
|
52
|
+
function injectMemorySection(body, enabled) {
|
|
53
|
+
if (!enabled)
|
|
54
|
+
return body;
|
|
55
|
+
if (!body || typeof body !== "object")
|
|
56
|
+
return body;
|
|
57
|
+
if (body.mode === "off")
|
|
58
|
+
return body;
|
|
59
|
+
if (!body.sections || typeof body.sections !== "object")
|
|
60
|
+
return body;
|
|
61
|
+
body.sections[exports.MEMORY_SECTION_NAME] = renderMemoryInstructions();
|
|
62
|
+
return body;
|
|
63
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaze/hicortex",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.4",
|
|
4
4
|
"description": "Self-learning memory for AI agents — experience captured automatically, distilled into lessons overnight, shared across your whole fleet. Works with Hermes, OpenClaw, Claude Code, and Pi.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|