@gamaze/hicortex 0.22.3 → 0.23.1

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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * The shared wrapper-prompt classifier (#489).
3
+ *
4
+ * ONE function imported by BOTH recall layers — the CC hook client
5
+ * (recall-hook-cli.ts buildHookRequest) and the server handler
6
+ * (recall-index.ts handleRecallIndex) — so the two can never drift on what
7
+ * counts as harness plumbing.
8
+ *
9
+ * What CC delivers as user-role wrapper messages (wild-verified over 250
10
+ * sampled session files + the latest live recall_pushes rows, #489
11
+ * refinement): `<task-notification>`, `<agent-message>`, local-command-caveat`,
12
+ * `<command-name>`/`<command-message>`/`<command-args>` (slash-command
13
+ * envelope), `<local-command-stdout>`, `<system-reminder>`, and
14
+ * `[Request interrupted…]` markers. These reach /recall-index verbatim today —
15
+ * ~15% of live pushes — inflating shown_count, burning hook latency, and
16
+ * polluting the Memory Precision denominator.
17
+ *
18
+ * The rule (owner decision 4, refinement A1 — skip ONLY pure plumbing):
19
+ * strip every known wrapper element, then measure PAYLOAD PROSE = the text
20
+ * left outside wrappers PLUS the bodies of `<result>` elements and
21
+ * `<agent-message>` elements (the payload channels — a subagent hand-back is
22
+ * real prose even though it arrives wrapped; the gold-set exception recalled
23
+ * usefully). Pure wrapper ⟺ payload prose is shorter than
24
+ * RECALL_MIN_PROMPT_CHARS — the SAME bar as the short-prompt gate: one
25
+ * constant, one meaning, "enough words to recall on". `<summary>` ("Agent X
26
+ * finished") and `<note>` are plumbing, never prose — otherwise every
27
+ * notification would pass and the skip would never fire.
28
+ *
29
+ * Conservative by construction:
30
+ * - NO wrapper marker at all → not a pure wrapper, whatever the length (a
31
+ * short plain prompt is the short-prompt gate's business, not this one).
32
+ * - A malformed or truncated wrapper does not match its strip regex, so its
33
+ * text counts as payload prose → not a pure wrapper → recalls.
34
+ * - An empty string is NOT classified here — the caller's empty check owns
35
+ * that case.
36
+ */
37
+ /**
38
+ * True when the prompt is PURE plumbing: after removing known wrapper
39
+ * elements, the payload prose (leftover text + result/agent-message bodies)
40
+ * is shorter than RECALL_MIN_PROMPT_CHARS. False for anything prose-bearing,
41
+ * malformed, wrapper-free, or empty — those recall exactly as today.
42
+ */
43
+ export declare function isPureWrapperPrompt(prompt: string): boolean;
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * The shared wrapper-prompt classifier (#489).
4
+ *
5
+ * ONE function imported by BOTH recall layers — the CC hook client
6
+ * (recall-hook-cli.ts buildHookRequest) and the server handler
7
+ * (recall-index.ts handleRecallIndex) — so the two can never drift on what
8
+ * counts as harness plumbing.
9
+ *
10
+ * What CC delivers as user-role wrapper messages (wild-verified over 250
11
+ * sampled session files + the latest live recall_pushes rows, #489
12
+ * refinement): `<task-notification>`, `<agent-message>`, local-command-caveat`,
13
+ * `<command-name>`/`<command-message>`/`<command-args>` (slash-command
14
+ * envelope), `<local-command-stdout>`, `<system-reminder>`, and
15
+ * `[Request interrupted…]` markers. These reach /recall-index verbatim today —
16
+ * ~15% of live pushes — inflating shown_count, burning hook latency, and
17
+ * polluting the Memory Precision denominator.
18
+ *
19
+ * The rule (owner decision 4, refinement A1 — skip ONLY pure plumbing):
20
+ * strip every known wrapper element, then measure PAYLOAD PROSE = the text
21
+ * left outside wrappers PLUS the bodies of `<result>` elements and
22
+ * `<agent-message>` elements (the payload channels — a subagent hand-back is
23
+ * real prose even though it arrives wrapped; the gold-set exception recalled
24
+ * usefully). Pure wrapper ⟺ payload prose is shorter than
25
+ * RECALL_MIN_PROMPT_CHARS — the SAME bar as the short-prompt gate: one
26
+ * constant, one meaning, "enough words to recall on". `<summary>` ("Agent X
27
+ * finished") and `<note>` are plumbing, never prose — otherwise every
28
+ * notification would pass and the skip would never fire.
29
+ *
30
+ * Conservative by construction:
31
+ * - NO wrapper marker at all → not a pure wrapper, whatever the length (a
32
+ * short plain prompt is the short-prompt gate's business, not this one).
33
+ * - A malformed or truncated wrapper does not match its strip regex, so its
34
+ * text counts as payload prose → not a pure wrapper → recalls.
35
+ * - An empty string is NOT classified here — the caller's empty check owns
36
+ * that case.
37
+ */
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.isPureWrapperPrompt = isPureWrapperPrompt;
40
+ const calibration_js_1 = require("./calibration.js");
41
+ /**
42
+ * Opening-tag detector — the precondition: only a prompt that actually
43
+ * CARRIES a known wrapper marker can be a pure wrapper. Bare and unclosed
44
+ * tags both match this; the strip pass below then decides how much survives
45
+ * as prose.
46
+ */
47
+ const WRAPPER_MARKER = /<(?:task-notification|agent-message|local-command-caveat|command-name|command-message|command-args|local-command-stdout|system-reminder|result)\b/;
48
+ /** Interrupt-marker presence — carries the same precondition weight as a
49
+ * wrapper tag (a marker-only prompt has no tags to detect). */
50
+ const INTERRUPT_MARKER_ANY = /\[Request interrupted by user[^\]]*\]/;
51
+ /**
52
+ * Wrapper element signatures. Non-greedy, bounded (the cleanMessageContent
53
+ * regex posture — no unbounded backtracking on pathological input; bodies
54
+ * beyond the cap fail to match and count as prose, the conservative
55
+ * direction). `[\s\S]` so multi-line bodies strip correctly.
56
+ *
57
+ * Payload channels (`task-notification`'s `<result>`, `agent-message` bodies)
58
+ * are handled separately below — their content is EXTRACTED as prose, not
59
+ * stripped as plumbing.
60
+ */
61
+ const WRAPPER_ELEMENTS = [
62
+ // task-notification: envelope stripped; an inner <result> body is harvested
63
+ // as prose by PAYLOAD_ELEMENT_BODIES (runs BEFORE this strip).
64
+ /<task-notification[^>]*>[\s\S]{0,50000}?<\/task-notification>/g,
65
+ /<local-command-caveat>[\s\S]{0,10000}?<\/local-command-caveat>/g,
66
+ /<command-name>[\s\S]{0,1000}?<\/command-name>/g,
67
+ /<command-message>[\s\S]{0,5000}?<\/command-message>/g,
68
+ /<command-args>[\s\S]{0,10000}?<\/command-args>/g,
69
+ /<local-command-stdout[^>]*>[\s\S]{0,100000}?<\/local-command-stdout>/g,
70
+ /<system-reminder[^>]*>[\s\S]{0,10000}?<\/system-reminder>/g,
71
+ // Payload-channel ENVELOPES strip here too — AFTER their bodies were
72
+ // harvested below (harvest runs first). The tags themselves are plumbing:
73
+ // an empty <agent-message></agent-message> must leave nothing behind, and
74
+ // a lone <result>…</result> must measure only its body.
75
+ /<agent-message[^>]*>[\s\S]{0,100000}?<\/agent-message>/g,
76
+ /<result[^>]*>[\s\S]{0,100000}?<\/result>/g,
77
+ ];
78
+ /**
79
+ * Payload channels — bodies that COUNT AS PROSE even though they sit inside a
80
+ * wrapper: the `<result>` of a task-notification (a report) and the full body
81
+ * of an `<agent-message>` (inter-agent prose, e.g. a subagent hand-back).
82
+ * `<agent-message>` is NOT in WRAPPER_ELEMENTS for exactly this reason: its
83
+ * whole body is payload, so it is harvested here and never stripped.
84
+ */
85
+ const PAYLOAD_ELEMENT_BODIES = [
86
+ /<result[^>]*>([\s\S]{0,100000}?)<\/result>/g,
87
+ /<agent-message[^>]*>([\s\S]{0,100000}?)<\/agent-message>/g,
88
+ ];
89
+ /** Interrupt markers — whole-line plumbing (either flavor). */
90
+ const INTERRUPT_MARKER = /^\s*\[Request interrupted by user[^\]]*\]\s*$/gm;
91
+ /**
92
+ * True when the prompt is PURE plumbing: after removing known wrapper
93
+ * elements, the payload prose (leftover text + result/agent-message bodies)
94
+ * is shorter than RECALL_MIN_PROMPT_CHARS. False for anything prose-bearing,
95
+ * malformed, wrapper-free, or empty — those recall exactly as today.
96
+ */
97
+ function isPureWrapperPrompt(prompt) {
98
+ if (!prompt)
99
+ return false;
100
+ if (!WRAPPER_MARKER.test(prompt) && !INTERRUPT_MARKER_ANY.test(prompt))
101
+ return false;
102
+ let payload = "";
103
+ // Harvest payload-channel bodies FIRST (agent-message is never stripped;
104
+ // task-notification's <result> is harvested before its envelope strips).
105
+ for (const re of PAYLOAD_ELEMENT_BODIES) {
106
+ for (const m of prompt.matchAll(re)) {
107
+ payload += " " + (m[1] ?? "");
108
+ }
109
+ }
110
+ // Strip the remaining wrapper envelopes + interrupt markers; what is left
111
+ // over is outside-wrapper prose.
112
+ let rest = prompt;
113
+ for (const re of WRAPPER_ELEMENTS) {
114
+ rest = rest.replace(re, " ");
115
+ }
116
+ rest = rest.replace(INTERRUPT_MARKER, " ");
117
+ payload += " " + rest;
118
+ // Whitespace-collapsed length is the prose bar — indentation and newlines
119
+ // are not words.
120
+ const prose = payload.replace(/\s+/g, " ").trim();
121
+ return prose.length < calibration_js_1.RECALL_MIN_PROMPT_CHARS;
122
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gamaze/hicortex",
3
- "version": "0.22.3",
3
+ "version": "0.23.1",
4
4
  "description": "Persistent agent identity for AI agents \u2014 a hand-edited identity layer, nightly-distilled experience, and lessons injected every session, shared across your whole fleet. Works with Hermes, OpenClaw, Claude Code, Pi, and opencode.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/server.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "name": "io.github.gamaze-labs/hicortex",
4
4
  "title": "Hicortex \u2014 AI Fleet Memory",
5
5
  "description": "Shared fleet memory for AI agents: nightly self-correction, recall every prompt (supported agents).",
6
- "version": "0.22.3",
6
+ "version": "0.23.1",
7
7
  "packages": [
8
8
  {
9
9
  "registryType": "npm",
10
10
  "identifier": "@gamaze/hicortex",
11
- "version": "0.22.3",
11
+ "version": "0.23.1",
12
12
  "transport": {
13
13
  "type": "stdio",
14
14
  "command": "npx",