@hyperspell/openclaw-hyperspell 0.21.1 → 0.22.0

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.
@@ -89,12 +89,19 @@ function contentToText(content) {
89
89
  }
90
90
  return "";
91
91
  }
92
- function messagesToTranscript(messages) {
92
+ /**
93
+ * Only conversational turns carry relationship signal. `system` is scaffolding
94
+ * and `tool`/`toolResult` are machinery — a Discord send receipt says nothing
95
+ * about how a conversation felt, and letting one through means the extractor
96
+ * distills API JSON into an emotional register. Same rule as hot-buffer.ts.
97
+ */
98
+ const CONVERSATIONAL_ROLES = new Set(["user", "assistant"]);
99
+ export function messagesToTranscript(messages) {
93
100
  const lines = [];
94
101
  for (const m of messages) {
95
102
  if (!m.role || !m.content)
96
103
  continue;
97
- if (m.role === "system")
104
+ if (!CONVERSATIONAL_ROLES.has(m.role))
98
105
  continue;
99
106
  const raw = contentToText(m.content);
100
107
  if (!raw)
@@ -112,9 +119,13 @@ function messagesToTranscript(messages) {
112
119
  * rather than a distilled emotional register. Real summaries are second-person
113
120
  * prose ("Your relationship with this user…"); the placeholder echoes the input
114
121
  * conversation, which has role-prefixed lines.
122
+ *
123
+ * Covers the full role vocabulary, not just what messagesToTranscript writes
124
+ * today: rows stored before tool roles were excluded above are still fetched
125
+ * until they age out, and they lead with `toolResult:`.
115
126
  */
116
127
  export function looksLikeRawTranscript(summary) {
117
- return /(^|\n)\s*(user|assistant)\s*:/i.test(summary);
128
+ return /(^|\n)\s*(?:user|assistant|system|tool(?:result|use|call)?)\s*:/i.test(summary);
118
129
  }
119
130
  /** Compact relative time for the arc labels (e.g. "just now", "3h ago", "2d ago"). */
120
131
  function relativeWhen(iso) {
package/dist/index.js CHANGED
@@ -144,6 +144,14 @@ export default {
144
144
  // Register exactly ONE of the two: cores between 2026-04 and 2026-07
145
145
  // accept both and would double-inject. Both hooks share the same
146
146
  // { prependContext } result contract and provide event.prompt.
147
+ //
148
+ // Do NOT rename this a third time. We were originally on
149
+ // `before_prompt_build`, moved to `before_agent_start`, and that is the
150
+ // only reason 2026.7.2 took injection down: `before_prompt_build` is
151
+ // still live in core's PROMPT_INJECTION_HOOK_NAMES and would have
152
+ // survived untouched. Staying on `agent_turn_prepare` (proven in
153
+ // production) — but the lesson is that "newer-sounding hook name" is not
154
+ // evidence of anything. Check core's hook table before moving again.
147
155
  const injectionHook = typeof api
148
156
  .enqueueNextTurnInjection === "function"
149
157
  ? "agent_turn_prepare"
@@ -2,7 +2,7 @@
2
2
  "id": "openclaw-hyperspell",
3
3
  "name": "Hyperspell",
4
4
  "description": "Context and memory for your AI agents — search across Notion, Slack, Google Drive, and more",
5
- "version": "0.21.0",
5
+ "version": "0.22.0",
6
6
  "kind": "memory",
7
7
  "contracts": {
8
8
  "tools": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperspell/openclaw-hyperspell",
3
- "version": "0.21.1",
3
+ "version": "0.22.0",
4
4
  "type": "module",
5
5
  "description": "OpenClaw Hyperspell memory plugin",
6
6
  "license": "MIT",