@psiclawops/hypermem 0.8.5 → 0.9.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.
- package/CHANGELOG.md +26 -0
- package/INSTALL.md +132 -9
- package/README.md +119 -272
- package/bench/README.md +42 -0
- package/bench/data-access-bench.mjs +380 -0
- package/bin/hypermem-bench.mjs +2 -0
- package/bin/hypermem-doctor.mjs +412 -0
- package/bin/hypermem-model-audit.mjs +339 -0
- package/bin/hypermem-status.mjs +491 -70
- package/dist/adaptive-lifecycle.d.ts +81 -0
- package/dist/adaptive-lifecycle.d.ts.map +1 -0
- package/dist/adaptive-lifecycle.js +190 -0
- package/dist/budget-policy.d.ts +1 -1
- package/dist/budget-policy.d.ts.map +1 -1
- package/dist/budget-policy.js +10 -5
- package/dist/cache.d.ts +1 -0
- package/dist/cache.d.ts.map +1 -1
- package/dist/cache.js +2 -0
- package/dist/composition-snapshot-integrity.d.ts +36 -0
- package/dist/composition-snapshot-integrity.d.ts.map +1 -0
- package/dist/composition-snapshot-integrity.js +131 -0
- package/dist/composition-snapshot-runtime.d.ts +59 -0
- package/dist/composition-snapshot-runtime.d.ts.map +1 -0
- package/dist/composition-snapshot-runtime.js +250 -0
- package/dist/composition-snapshot-store.d.ts +44 -0
- package/dist/composition-snapshot-store.d.ts.map +1 -0
- package/dist/composition-snapshot-store.js +117 -0
- package/dist/compositor.d.ts +125 -1
- package/dist/compositor.d.ts.map +1 -1
- package/dist/compositor.js +692 -44
- package/dist/doc-chunk-store.d.ts +19 -0
- package/dist/doc-chunk-store.d.ts.map +1 -1
- package/dist/doc-chunk-store.js +56 -6
- package/dist/hybrid-retrieval.d.ts +38 -0
- package/dist/hybrid-retrieval.d.ts.map +1 -1
- package/dist/hybrid-retrieval.js +86 -1
- package/dist/index.d.ts +12 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -2
- package/dist/knowledge-store.d.ts +4 -1
- package/dist/knowledge-store.d.ts.map +1 -1
- package/dist/knowledge-store.js +27 -4
- package/dist/library-schema.d.ts +12 -8
- package/dist/library-schema.d.ts.map +1 -1
- package/dist/library-schema.js +22 -8
- package/dist/message-store.d.ts.map +1 -1
- package/dist/message-store.js +7 -3
- package/dist/metrics-dashboard.d.ts +18 -1
- package/dist/metrics-dashboard.d.ts.map +1 -1
- package/dist/metrics-dashboard.js +52 -14
- package/dist/reranker.d.ts +1 -1
- package/dist/reranker.js +2 -2
- package/dist/schema.d.ts +1 -1
- package/dist/schema.d.ts.map +1 -1
- package/dist/schema.js +28 -1
- package/dist/seed.d.ts.map +1 -1
- package/dist/seed.js +2 -0
- package/dist/topic-synthesizer.d.ts +20 -0
- package/dist/topic-synthesizer.d.ts.map +1 -1
- package/dist/topic-synthesizer.js +113 -3
- package/dist/trigger-registry.d.ts.map +1 -1
- package/dist/trigger-registry.js +10 -2
- package/dist/types.d.ts +271 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +7 -7
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +17 -7
- package/docs/DIAGNOSTICS.md +205 -0
- package/docs/INTEGRATION_VALIDATION.md +186 -0
- package/docs/MIGRATION.md +9 -6
- package/docs/MIGRATION_GUIDE.md +125 -101
- package/docs/ROADMAP.md +238 -20
- package/docs/TUNING.md +19 -5
- package/install.sh +152 -401
- package/memory-plugin/LICENSE +190 -0
- package/memory-plugin/README.md +20 -0
- package/memory-plugin/dist/index.js +50 -0
- package/memory-plugin/package.json +2 -2
- package/package.json +18 -4
- package/plugin/LICENSE +190 -0
- package/plugin/README.md +20 -0
- package/plugin/dist/index.d.ts +29 -0
- package/plugin/dist/index.d.ts.map +1 -1
- package/plugin/dist/index.js +288 -23
- package/plugin/dist/index.js.map +1 -1
- package/plugin/package.json +2 -2
- package/scripts/install-runtime.mjs +12 -1
package/install.sh
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# HyperMem
|
|
2
|
+
# HyperMem npm-first installer and upgrader
|
|
3
3
|
# curl -fsSL https://raw.githubusercontent.com/PsiClawOps/hypermem/main/install.sh | bash
|
|
4
4
|
set -euo pipefail
|
|
5
5
|
|
|
6
|
-
# ─────────────────────────────────────────────
|
|
7
|
-
# Colors
|
|
8
|
-
# ─────────────────────────────────────────────
|
|
9
6
|
RED='\033[0;31m'
|
|
10
7
|
GREEN='\033[0;32m'
|
|
11
8
|
YELLOW='\033[1;33m'
|
|
@@ -14,307 +11,144 @@ BOLD='\033[1m'
|
|
|
14
11
|
DIM='\033[2m'
|
|
15
12
|
NC='\033[0m'
|
|
16
13
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
14
|
+
PACKAGE="${HYPERMEM_PACKAGE:-@psiclawops/hypermem@latest}"
|
|
15
|
+
INSTALL_DIR="${HYPERMEM_INSTALL_DIR:-$HOME/.hypermem}"
|
|
16
|
+
RUNTIME_DIR="${HYPERMEM_RUNTIME_DIR:-$HOME/.openclaw/plugins/hypermem}"
|
|
17
|
+
CONFIG_FILE="$HOME/.openclaw/hypermem/config.json"
|
|
18
|
+
ASSUME_YES=false
|
|
19
|
+
SKIP_NPM=false
|
|
20
|
+
SKIP_STAGE=false
|
|
21
|
+
|
|
22
|
+
usage() {
|
|
23
|
+
cat <<EOF
|
|
24
|
+
HyperMem installer
|
|
25
|
+
|
|
26
|
+
Usage: install.sh [options]
|
|
27
|
+
|
|
28
|
+
Options:
|
|
29
|
+
--yes non-interactive defaults
|
|
30
|
+
--package <spec> npm package spec, default: @psiclawops/hypermem@latest
|
|
31
|
+
--install-dir <p> npm install directory, default: ~/.hypermem
|
|
32
|
+
--runtime-dir <p> staged OpenClaw runtime dir, default: ~/.openclaw/plugins/hypermem
|
|
33
|
+
--skip-npm use existing package in install dir
|
|
34
|
+
--skip-stage install package only, do not run hypermem-install
|
|
35
|
+
--help show this help
|
|
36
|
+
|
|
37
|
+
Environment overrides:
|
|
38
|
+
HYPERMEM_PACKAGE, HYPERMEM_INSTALL_DIR, HYPERMEM_RUNTIME_DIR
|
|
39
|
+
|
|
40
|
+
This script stages HyperMem. It does not edit OpenClaw config and does not restart the gateway.
|
|
41
|
+
EOF
|
|
32
42
|
}
|
|
33
43
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
while [[ $# -gt 0 ]]; do
|
|
45
|
+
case "$1" in
|
|
46
|
+
--yes|-y) ASSUME_YES=true; shift ;;
|
|
47
|
+
--package) PACKAGE="$2"; shift 2 ;;
|
|
48
|
+
--install-dir) INSTALL_DIR="$2"; shift 2 ;;
|
|
49
|
+
--runtime-dir) RUNTIME_DIR="$2"; shift 2 ;;
|
|
50
|
+
--skip-npm) SKIP_NPM=true; shift ;;
|
|
51
|
+
--skip-stage) SKIP_STAGE=true; shift ;;
|
|
52
|
+
--help|-h) usage; exit 0 ;;
|
|
53
|
+
*) echo -e "${RED}Unknown option:${NC} $1" >&2; usage; exit 1 ;;
|
|
54
|
+
esac
|
|
55
|
+
done
|
|
42
56
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
echo -ne " ${BOLD}${question}${NC} ${DIM}[${default}]${NC} "
|
|
48
|
-
else
|
|
49
|
-
echo -ne " ${BOLD}${question}${NC} "
|
|
50
|
-
fi
|
|
51
|
-
read -r reply </dev/tty || { [[ -n "$default" ]] && reply="$default" || die "Cannot read input (not a terminal?). Run: bash <(curl -fsSL ...) instead."; }
|
|
52
|
-
[[ -z "$reply" && -n "$default" ]] && reply="$default"
|
|
53
|
-
printf -v "$var" '%s' "$reply"
|
|
54
|
-
}
|
|
57
|
+
info() { echo -e " ${CYAN}→${NC} $*"; }
|
|
58
|
+
success() { echo -e " ${GREEN}✓${NC} $*"; }
|
|
59
|
+
warn() { echo -e " ${YELLOW}⚠${NC} $*"; }
|
|
60
|
+
die() { echo -e " ${RED}✗${NC} $*" >&2; exit 1; }
|
|
55
61
|
|
|
56
62
|
confirm() {
|
|
57
|
-
|
|
63
|
+
if $ASSUME_YES; then return 0; fi
|
|
58
64
|
echo -ne " ${BOLD}$1${NC} ${DIM}[y/N]${NC} "
|
|
59
65
|
read -r reply </dev/tty || return 1
|
|
60
66
|
[[ "$reply" =~ ^[Yy] ]]
|
|
61
67
|
}
|
|
62
68
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
echo
|
|
68
|
-
|
|
69
|
-
# bash version
|
|
70
|
-
if (( BASH_VERSINFO[0] < 4 )); then
|
|
71
|
-
die "bash 4+ required (you have $BASH_VERSION)"
|
|
72
|
-
fi
|
|
73
|
-
success "bash $BASH_VERSION"
|
|
74
|
-
|
|
75
|
-
# curl
|
|
76
|
-
command -v curl &>/dev/null || die "curl is required"
|
|
77
|
-
success "curl $(curl --version | head -1 | awk '{print $2}')"
|
|
78
|
-
|
|
79
|
-
# git (optional — only needed for dev installs)
|
|
80
|
-
|
|
81
|
-
# node
|
|
82
|
-
command -v node &>/dev/null || die "Node.js is required (v22+)"
|
|
83
|
-
NODE_VERSION=$(node --version | sed 's/v//')
|
|
84
|
-
NODE_MAJOR=$(echo "$NODE_VERSION" | cut -d. -f1)
|
|
85
|
-
(( NODE_MAJOR >= 22 )) || die "Node.js v22+ required (you have v$NODE_VERSION — HyperMem requires v22+)"
|
|
86
|
-
success "node v$NODE_VERSION"
|
|
87
|
-
|
|
88
|
-
# npm
|
|
89
|
-
command -v npm &>/dev/null || die "npm is required"
|
|
90
|
-
success "npm $(npm --version)"
|
|
69
|
+
banner() {
|
|
70
|
+
echo ""
|
|
71
|
+
echo -e "${CYAN}${BOLD} HyperMem installer${NC}"
|
|
72
|
+
echo -e " ${DIM}npm package install + OpenClaw runtime staging${NC}"
|
|
73
|
+
echo ""
|
|
91
74
|
}
|
|
92
75
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# NVIDIA GPU
|
|
106
|
-
if command -v nvidia-smi &>/dev/null; then
|
|
107
|
-
GPU_NAME=$(nvidia-smi --query-gpu=name --format=csv,noheader 2>/dev/null | head -1 || echo "unknown")
|
|
108
|
-
HAS_NVIDIA=true
|
|
109
|
-
success "NVIDIA GPU: $GPU_NAME"
|
|
110
|
-
else
|
|
111
|
-
info "No NVIDIA GPU detected"
|
|
112
|
-
fi
|
|
113
|
-
|
|
114
|
-
# AMD GPU
|
|
115
|
-
if command -v rocm-smi &>/dev/null || lspci 2>/dev/null | grep -qi 'amd.*display\|radeon'; then
|
|
116
|
-
HAS_AMD=true
|
|
117
|
-
success "AMD GPU detected"
|
|
118
|
-
fi
|
|
119
|
-
|
|
120
|
-
# Ollama
|
|
121
|
-
if command -v ollama &>/dev/null; then
|
|
122
|
-
OLLAMA_VERSION=$(ollama --version 2>/dev/null || echo "unknown")
|
|
123
|
-
HAS_OLLAMA=true
|
|
124
|
-
success "Ollama: $OLLAMA_VERSION"
|
|
125
|
-
else
|
|
126
|
-
info "Ollama not found"
|
|
127
|
-
fi
|
|
128
|
-
|
|
129
|
-
# API key (OpenRouter or OpenAI-compatible) — informational only, does NOT affect recommendation
|
|
130
|
-
if [[ -n "${OPENROUTER_API_KEY:-}" || -n "${HYPERMEM_EMBED_API_KEY:-}" ]]; then
|
|
131
|
-
HAS_API_KEY=true
|
|
132
|
-
info "Embedding API key detected (Tier 4 available)"
|
|
133
|
-
else
|
|
134
|
-
info "No embedding API key in environment"
|
|
135
|
-
fi
|
|
76
|
+
preflight() {
|
|
77
|
+
echo -e "${BOLD} Preflight${NC}"
|
|
78
|
+
command -v node >/dev/null 2>&1 || die "Node.js v22+ is required"
|
|
79
|
+
local node_version node_major
|
|
80
|
+
node_version="$(node --version | sed 's/^v//')"
|
|
81
|
+
node_major="${node_version%%.*}"
|
|
82
|
+
[[ "$node_major" =~ ^[0-9]+$ ]] || die "Cannot parse Node.js version: $node_version"
|
|
83
|
+
(( node_major >= 22 )) || die "Node.js v22+ required, found v$node_version"
|
|
84
|
+
success "node v$node_version"
|
|
85
|
+
|
|
86
|
+
command -v npm >/dev/null 2>&1 || die "npm is required"
|
|
87
|
+
success "npm $(npm --version)"
|
|
136
88
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
elif $HAS_NVIDIA || $HAS_AMD; then
|
|
141
|
-
# GPU present but no Ollama — recommend Tier 2, note Tier 3 needs Ollama
|
|
142
|
-
DETECTED_TIER=2
|
|
89
|
+
if command -v openclaw >/dev/null 2>&1; then
|
|
90
|
+
success "openclaw CLI found"
|
|
91
|
+
openclaw gateway status >/dev/null 2>&1 || warn "OpenClaw gateway is not running or not onboarded yet. Complete OpenClaw setup before activation."
|
|
143
92
|
else
|
|
144
|
-
|
|
145
|
-
DETECTED_TIER=2
|
|
93
|
+
warn "openclaw CLI not found. HyperMem can be staged now, but activation requires OpenClaw."
|
|
146
94
|
fi
|
|
147
95
|
}
|
|
148
96
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
# ─────────────────────────────────────────────
|
|
152
|
-
select_tier() {
|
|
153
|
-
echo -e "\n${BOLD} Memory tier selection${NC}\n"
|
|
154
|
-
|
|
155
|
-
echo -e " ${DIM}Choose how HyperMem handles semantic memory retrieval:${NC}\n"
|
|
156
|
-
|
|
157
|
-
echo -e " ${BOLD}1)${NC} ${GREEN}FTS5 + BM25${NC} ${DIM}(Tier 1 — keyword search only)${NC}"
|
|
158
|
-
echo -e " No embedder. Fast, zero extra dependencies."
|
|
159
|
-
echo -e " Best for: minimal setups, very low spec hardware.\n"
|
|
160
|
-
|
|
161
|
-
echo -e " ${BOLD}2)${NC} ${GREEN}MiniLM-L6-v2${NC} ${DIM}(Tier 2 — lightweight semantic)${NC}"
|
|
162
|
-
echo -e " 384-dimension embedder, runs in Node via WASM. No GPU, no Ollama."
|
|
163
|
-
echo -e " Best for: CPU-only servers, Raspberry Pi, low-memory VMs.\n"
|
|
164
|
-
|
|
165
|
-
echo -e " ${BOLD}3)${NC} ${GREEN}nomic-embed-text${NC} ${DIM}(Tier 3 — GPU-accelerated local)${NC}"
|
|
166
|
-
echo -e " 768-dimension embedder via Ollama. GPU strongly recommended."
|
|
167
|
-
echo -e " Best for: local workstations with a GPU, self-hosted setups.\n"
|
|
168
|
-
|
|
169
|
-
echo -e " ${BOLD}4)${NC} ${GREEN}qwen3-embedding:8b${NC} ${DIM}(Tier 4 — API, top quality)${NC}"
|
|
170
|
-
echo -e " 4096-dimension embedder via OpenRouter (or any OpenAI-compatible API)."
|
|
171
|
-
echo -e " Best for: production deployments, highest retrieval quality.\n"
|
|
172
|
-
|
|
173
|
-
echo -e " ${DIM}Recommended for your hardware: ${NC}${BOLD}Tier ${DETECTED_TIER}${NC}"
|
|
174
|
-
$HAS_API_KEY && echo -e " ${DIM}(Tier 4 also available — API key detected in environment)${NC}"
|
|
175
|
-
echo ""
|
|
176
|
-
|
|
177
|
-
while true; do
|
|
178
|
-
prompt TIER_INPUT "Select tier (1-4):" "$DETECTED_TIER"
|
|
179
|
-
if [[ "$TIER_INPUT" =~ ^[1-4]$ ]]; then
|
|
180
|
-
SELECTED_TIER="$TIER_INPUT"
|
|
181
|
-
break
|
|
182
|
-
fi
|
|
183
|
-
warn "Enter a number between 1 and 4"
|
|
184
|
-
done
|
|
185
|
-
|
|
186
|
-
echo ""
|
|
187
|
-
case "$SELECTED_TIER" in
|
|
188
|
-
1) success "Tier 1: FTS5+BM25 — no embedder needed" ;;
|
|
189
|
-
2) success "Tier 2: MiniLM-L6-v2 via @huggingface/transformers" ;;
|
|
190
|
-
3) success "Tier 3: nomic-embed-text via Ollama" ;;
|
|
191
|
-
4) success "Tier 4: qwen3-embedding:8b via OpenRouter" ;;
|
|
192
|
-
esac
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
# ─────────────────────────────────────────────
|
|
196
|
-
# Install HyperMem
|
|
197
|
-
# ─────────────────────────────────────────────
|
|
198
|
-
INSTALL_DIR="${HYPERMEM_INSTALL_DIR:-$HOME/.hypermem}"
|
|
199
|
-
|
|
200
|
-
install_hypermem() {
|
|
201
|
-
echo -e "\n${BOLD} Installing HyperMem${NC}"
|
|
202
|
-
|
|
97
|
+
install_package() {
|
|
98
|
+
echo -e "\n${BOLD} Package install${NC}"
|
|
203
99
|
mkdir -p "$INSTALL_DIR"
|
|
204
|
-
|
|
205
|
-
# Initialize package.json if this is a fresh install
|
|
206
100
|
if [[ ! -f "$INSTALL_DIR/package.json" ]]; then
|
|
207
|
-
info "
|
|
208
|
-
npm --prefix "$INSTALL_DIR" init -y --silent
|
|
101
|
+
info "initializing $INSTALL_DIR"
|
|
102
|
+
npm --prefix "$INSTALL_DIR" init -y --silent >/dev/null
|
|
209
103
|
fi
|
|
210
104
|
|
|
211
|
-
if
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
else
|
|
216
|
-
info "Using existing installation"
|
|
217
|
-
fi
|
|
218
|
-
else
|
|
219
|
-
info "Installing @psiclawops/hypermem..."
|
|
220
|
-
npm --prefix "$INSTALL_DIR" install --silent @psiclawops/hypermem@latest
|
|
221
|
-
|
|
222
|
-
info "Installing @psiclawops/hypercompositor..."
|
|
223
|
-
npm --prefix "$INSTALL_DIR" install --silent @psiclawops/hypercompositor@latest
|
|
224
|
-
|
|
225
|
-
info "Installing @psiclawops/hypermem-memory..."
|
|
226
|
-
npm --prefix "$INSTALL_DIR" install --silent @psiclawops/hypermem-memory@latest
|
|
105
|
+
if $SKIP_NPM; then
|
|
106
|
+
[[ -d "$INSTALL_DIR/node_modules/@psiclawops/hypermem" ]] || die "--skip-npm requested but package is missing in $INSTALL_DIR"
|
|
107
|
+
success "using existing package in $INSTALL_DIR"
|
|
108
|
+
return
|
|
227
109
|
fi
|
|
228
110
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
success "HyperMem installed at $INSTALL_DIR"
|
|
111
|
+
info "installing $PACKAGE"
|
|
112
|
+
npm --prefix "$INSTALL_DIR" install --silent "$PACKAGE"
|
|
113
|
+
success "package installed in $INSTALL_DIR"
|
|
234
114
|
}
|
|
235
115
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
EMBED_MODEL="none"
|
|
247
|
-
EMBED_DIMS=0
|
|
248
|
-
success "No embedder required"
|
|
249
|
-
;;
|
|
250
|
-
|
|
251
|
-
2)
|
|
252
|
-
info "Installing @huggingface/transformers (WASM embedder)..."
|
|
253
|
-
npm --prefix "$INSTALL_DIR" install --silent @huggingface/transformers@3
|
|
254
|
-
EMBED_PROVIDER="transformers"
|
|
255
|
-
EMBED_MODEL="Xenova/all-MiniLM-L6-v2"
|
|
256
|
-
EMBED_DIMS=384
|
|
257
|
-
success "MiniLM-L6-v2 will download on first use (~90MB)"
|
|
258
|
-
;;
|
|
259
|
-
|
|
260
|
-
3)
|
|
261
|
-
if ! command -v ollama &>/dev/null; then
|
|
262
|
-
die "Ollama is required for Tier 3. Install it from https://ollama.com then re-run."
|
|
263
|
-
fi
|
|
264
|
-
info "Pulling nomic-embed-text via Ollama..."
|
|
265
|
-
ollama pull nomic-embed-text
|
|
266
|
-
EMBED_PROVIDER="ollama"
|
|
267
|
-
EMBED_MODEL="nomic-embed-text"
|
|
268
|
-
EMBED_DIMS=768
|
|
269
|
-
success "nomic-embed-text ready"
|
|
270
|
-
;;
|
|
271
|
-
|
|
272
|
-
4)
|
|
273
|
-
# Get API key
|
|
274
|
-
API_KEY="${OPENROUTER_API_KEY:-${HYPERMEM_EMBED_API_KEY:-}}"
|
|
275
|
-
if [[ -z "$API_KEY" ]]; then
|
|
276
|
-
echo ""
|
|
277
|
-
echo -e " ${DIM}Get a key at https://openrouter.ai/keys${NC}"
|
|
278
|
-
prompt API_KEY "OpenRouter API key:"
|
|
279
|
-
[[ -z "$API_KEY" ]] && die "API key required for Tier 4"
|
|
280
|
-
else
|
|
281
|
-
success "Using API key from environment"
|
|
282
|
-
fi
|
|
283
|
-
EMBED_PROVIDER="openai"
|
|
284
|
-
EMBED_MODEL="qwen/qwen3-embedding:8b"
|
|
285
|
-
EMBED_DIMS=4096
|
|
286
|
-
EMBED_API_KEY="$API_KEY"
|
|
287
|
-
EMBED_BASE_URL="https://openrouter.ai/api/v1"
|
|
288
|
-
success "Tier 4 configured — qwen3-embedding:8b via OpenRouter"
|
|
289
|
-
;;
|
|
290
|
-
esac
|
|
116
|
+
backup_runtime() {
|
|
117
|
+
[[ -e "$RUNTIME_DIR" ]] || return 0
|
|
118
|
+
local backup
|
|
119
|
+
backup="${RUNTIME_DIR}.backup.$(date +%Y%m%d-%H%M%S)"
|
|
120
|
+
if confirm "Existing runtime found at $RUNTIME_DIR. Back it up before replacing?"; then
|
|
121
|
+
cp -a "$RUNTIME_DIR" "$backup"
|
|
122
|
+
success "backup written to $backup"
|
|
123
|
+
else
|
|
124
|
+
warn "continuing without runtime backup"
|
|
125
|
+
fi
|
|
291
126
|
}
|
|
292
127
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
128
|
+
stage_runtime() {
|
|
129
|
+
echo -e "\n${BOLD} Runtime staging${NC}"
|
|
130
|
+
if $SKIP_STAGE; then
|
|
131
|
+
warn "runtime staging skipped"
|
|
132
|
+
return
|
|
133
|
+
fi
|
|
298
134
|
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
135
|
+
local installer="$INSTALL_DIR/node_modules/@psiclawops/hypermem/scripts/install-runtime.mjs"
|
|
136
|
+
[[ -f "$installer" ]] || die "missing runtime installer: $installer"
|
|
137
|
+
backup_runtime
|
|
138
|
+
node "$installer" "$RUNTIME_DIR"
|
|
139
|
+
success "runtime staged to $RUNTIME_DIR"
|
|
140
|
+
}
|
|
302
141
|
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
elif [[ "$SELECTED_TIER" == "3" ]]; then
|
|
309
|
-
EMBED_BLOCK="\"embedding\": { \"provider\": \"ollama\", \"model\": \"$EMBED_MODEL\", \"dimensions\": $EMBED_DIMS, \"ollamaUrl\": \"http://localhost:11434\" }"
|
|
310
|
-
else
|
|
311
|
-
EMBED_BLOCK="\"embedding\": { \"provider\": \"openai\", \"model\": \"$EMBED_MODEL\", \"dimensions\": $EMBED_DIMS, \"openaiBaseUrl\": \"$EMBED_BASE_URL\", \"openaiApiKey\": \"$EMBED_API_KEY\" }"
|
|
142
|
+
write_minimal_config_if_missing() {
|
|
143
|
+
echo -e "\n${BOLD} Config check${NC}"
|
|
144
|
+
if [[ -f "$CONFIG_FILE" ]]; then
|
|
145
|
+
success "existing config preserved: $CONFIG_FILE"
|
|
146
|
+
return
|
|
312
147
|
fi
|
|
313
148
|
|
|
314
|
-
|
|
149
|
+
mkdir -p "$(dirname "$CONFIG_FILE")"
|
|
150
|
+
cat > "$CONFIG_FILE" <<'JSON'
|
|
315
151
|
{
|
|
316
|
-
"installDir": "$INSTALL_DIR",
|
|
317
|
-
"tier": $SELECTED_TIER,
|
|
318
152
|
"contextWindowSize": 128000,
|
|
319
153
|
"contextWindowReserve": 0.25,
|
|
320
154
|
"deferToolPruning": false,
|
|
@@ -322,6 +156,9 @@ write_config() {
|
|
|
322
156
|
"contextWindowOverrides": {},
|
|
323
157
|
"warmCacheReplayThresholdMs": 120000,
|
|
324
158
|
"subagentWarming": "light",
|
|
159
|
+
"embedding": {
|
|
160
|
+
"provider": "none"
|
|
161
|
+
},
|
|
325
162
|
"compositor": {
|
|
326
163
|
"budgetFraction": 0.55,
|
|
327
164
|
"reserveFraction": 0.25,
|
|
@@ -363,154 +200,68 @@ write_config() {
|
|
|
363
200
|
"recentConversationCooldownMs": 30000,
|
|
364
201
|
"maxCandidatesPerPass": 200
|
|
365
202
|
},
|
|
366
|
-
$EMBED_BLOCK,
|
|
367
203
|
"vectorStore": {
|
|
368
|
-
"enabled":
|
|
204
|
+
"enabled": false
|
|
369
205
|
}
|
|
370
206
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
success "Config written to $CONFIG_FILE"
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
# ─────────────────────────────────────────────
|
|
377
|
-
# OpenClaw plugin registration
|
|
378
|
-
# ─────────────────────────────────────────────
|
|
379
|
-
register_plugin() {
|
|
380
|
-
if ! command -v openclaw &>/dev/null; then
|
|
381
|
-
warn "OpenClaw CLI not found, skipping plugin registration"
|
|
382
|
-
echo -e " ${DIM}Run these manually after installing OpenClaw:${NC}"
|
|
383
|
-
echo -e " ${DIM} openclaw plugins install file:$PLUGIN_DIR${NC}"
|
|
384
|
-
echo -e " ${DIM} openclaw plugins install file:$MEMORY_PLUGIN_DIR${NC}"
|
|
385
|
-
return
|
|
386
|
-
fi
|
|
387
|
-
|
|
388
|
-
echo ""
|
|
389
|
-
if confirm "Register HyperMem plugins with OpenClaw?"; then
|
|
390
|
-
# Context engine plugin (hypercompositor)
|
|
391
|
-
info "Registering context engine plugin (hypercompositor)..."
|
|
392
|
-
if openclaw plugins install "file:$PLUGIN_DIR" 2>/dev/null; then
|
|
393
|
-
success "hypercompositor registered"
|
|
394
|
-
else
|
|
395
|
-
warn "Context engine registration failed — run: openclaw plugins install file:$PLUGIN_DIR"
|
|
396
|
-
fi
|
|
397
|
-
|
|
398
|
-
# Memory plugin (hypermem)
|
|
399
|
-
info "Registering memory plugin (hypermem)..."
|
|
400
|
-
if openclaw plugins install "file:$MEMORY_PLUGIN_DIR" 2>/dev/null; then
|
|
401
|
-
success "hypermem registered"
|
|
402
|
-
else
|
|
403
|
-
warn "Memory plugin registration failed — run: openclaw plugins install file:$MEMORY_PLUGIN_DIR"
|
|
404
|
-
fi
|
|
405
|
-
|
|
406
|
-
# Configure plugin slots
|
|
407
|
-
info "Configuring plugin slots..."
|
|
408
|
-
local SLOT_OK=true
|
|
409
|
-
openclaw config set plugins.slots.contextEngine hypercompositor 2>/dev/null || SLOT_OK=false
|
|
410
|
-
openclaw config set plugins.slots.memory hypermem 2>/dev/null || SLOT_OK=false
|
|
411
|
-
if $SLOT_OK; then
|
|
412
|
-
success "Plugin slots configured"
|
|
413
|
-
else
|
|
414
|
-
warn "Slot config failed — set manually:"
|
|
415
|
-
echo -e " ${DIM} openclaw config set plugins.slots.contextEngine hypercompositor${NC}"
|
|
416
|
-
echo -e " ${DIM} openclaw config set plugins.slots.memory hypermem${NC}"
|
|
417
|
-
fi
|
|
418
|
-
|
|
419
|
-
success "Restart OpenClaw to activate: openclaw gateway restart"
|
|
420
|
-
fi
|
|
207
|
+
JSON
|
|
208
|
+
success "lightweight starter config written: $CONFIG_FILE"
|
|
421
209
|
}
|
|
422
210
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
import { readFileSync, existsSync } from 'fs';
|
|
432
|
-
const cfg = JSON.parse(readFileSync('$HOME/.openclaw/hypermem/config.json', 'utf8'));
|
|
433
|
-
if (!cfg.tier) throw new Error('missing tier');
|
|
434
|
-
if (!cfg.installDir) throw new Error('missing installDir');
|
|
435
|
-
if (!existsSync(cfg.installDir)) throw new Error('installDir does not exist: ' + cfg.installDir);
|
|
436
|
-
EOF
|
|
437
|
-
|
|
438
|
-
# Verify HyperMem core module loads
|
|
439
|
-
node --input-type=module <<EOF 2>/dev/null \
|
|
440
|
-
&& success "HyperMem core module loads" \
|
|
441
|
-
|| warn "HyperMem core module load failed — check $INSTALL_DIR/node_modules/@psiclawops/hypermem"
|
|
442
|
-
import { createRequire } from 'module';
|
|
443
|
-
const require = createRequire(import.meta.url);
|
|
444
|
-
require('$INSTALL_DIR/node_modules/@psiclawops/hypermem/dist/index.js');
|
|
445
|
-
EOF
|
|
446
|
-
|
|
447
|
-
# Verify context engine plugin dist exists
|
|
448
|
-
[[ -f "$PLUGIN_DIR/dist/index.js" ]] \
|
|
449
|
-
&& success "hypercompositor plugin built" \
|
|
450
|
-
|| warn "hypercompositor plugin not built — reinstall: npm --prefix $INSTALL_DIR install @psiclawops/hypercompositor@latest"
|
|
451
|
-
|
|
452
|
-
# Verify memory plugin dist exists
|
|
453
|
-
[[ -f "$MEMORY_PLUGIN_DIR/dist/index.js" ]] \
|
|
454
|
-
&& success "hypermem memory plugin built" \
|
|
455
|
-
|| warn "hypermem memory plugin not built — reinstall: npm --prefix $INSTALL_DIR install @psiclawops/hypermem-memory@latest"
|
|
456
|
-
|
|
457
|
-
# Tier 2: verify transformers package is present
|
|
458
|
-
if [[ "$SELECTED_TIER" == "2" ]]; then
|
|
459
|
-
[[ -d "$INSTALL_DIR/node_modules/@huggingface/transformers" ]] \
|
|
460
|
-
&& success "@huggingface/transformers present" \
|
|
461
|
-
|| warn "@huggingface/transformers missing — run: npm --prefix $INSTALL_DIR install @huggingface/transformers@3"
|
|
462
|
-
fi
|
|
463
|
-
|
|
464
|
-
# Tier 3: verify nomic model is available in Ollama
|
|
465
|
-
if [[ "$SELECTED_TIER" == "3" ]] && command -v ollama &>/dev/null; then
|
|
466
|
-
ollama list 2>/dev/null | grep -q 'nomic-embed-text' \
|
|
467
|
-
&& success "nomic-embed-text present in Ollama" \
|
|
468
|
-
|| warn "nomic-embed-text not found in Ollama — run: ollama pull nomic-embed-text"
|
|
469
|
-
fi
|
|
211
|
+
verify_stage() {
|
|
212
|
+
echo -e "\n${BOLD} Stage verification${NC}"
|
|
213
|
+
[[ -d "$RUNTIME_DIR/dist" ]] || die "missing $RUNTIME_DIR/dist"
|
|
214
|
+
[[ -d "$RUNTIME_DIR/plugin/dist" ]] || die "missing $RUNTIME_DIR/plugin/dist"
|
|
215
|
+
[[ -d "$RUNTIME_DIR/memory-plugin/dist" ]] || die "missing $RUNTIME_DIR/memory-plugin/dist"
|
|
216
|
+
[[ -f "$RUNTIME_DIR/bin/hypermem-status.mjs" ]] || die "missing hypermem-status bin"
|
|
217
|
+
[[ -f "$RUNTIME_DIR/bin/hypermem-model-audit.mjs" ]] || die "missing hypermem-model-audit bin"
|
|
218
|
+
success "runtime payload complete"
|
|
470
219
|
}
|
|
471
220
|
|
|
472
|
-
|
|
473
|
-
# Summary
|
|
474
|
-
# ─────────────────────────────────────────────
|
|
475
|
-
summary() {
|
|
221
|
+
next_steps() {
|
|
476
222
|
echo ""
|
|
477
|
-
echo -e "${CYAN}${BOLD}
|
|
478
|
-
echo -e "${CYAN}${BOLD} HyperMem installed${NC}"
|
|
479
|
-
echo -e "${CYAN}${BOLD} ─────────────────────────────────────────${NC}"
|
|
223
|
+
echo -e "${CYAN}${BOLD} HyperMem staged${NC}"
|
|
480
224
|
echo ""
|
|
481
|
-
echo -e " ${BOLD}
|
|
225
|
+
echo -e " ${BOLD}Package:${NC} $PACKAGE"
|
|
482
226
|
echo -e " ${BOLD}Install:${NC} $INSTALL_DIR"
|
|
483
|
-
echo -e " ${BOLD}
|
|
484
|
-
echo -e " ${BOLD}
|
|
227
|
+
echo -e " ${BOLD}Runtime:${NC} $RUNTIME_DIR"
|
|
228
|
+
echo -e " ${BOLD}Config:${NC} $CONFIG_FILE"
|
|
485
229
|
echo ""
|
|
230
|
+
echo -e " ${BOLD}Activation commands:${NC}"
|
|
231
|
+
cat <<EOF
|
|
232
|
+
openclaw config get plugins.load.paths
|
|
233
|
+
openclaw config get plugins.allow
|
|
486
234
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
4) echo -e " ${DIM}qwen3-embedding:8b via OpenRouter. API key stored in config.${NC}" ;;
|
|
492
|
-
esac
|
|
235
|
+
HYPERMEM_PATHS="[\"${RUNTIME_DIR}/plugin\",\"${RUNTIME_DIR}/memory-plugin\"]"
|
|
236
|
+
openclaw config set plugins.load.paths "\$HYPERMEM_PATHS" --strict-json
|
|
237
|
+
openclaw config set plugins.slots.contextEngine hypercompositor
|
|
238
|
+
openclaw config set plugins.slots.memory hypermem
|
|
493
239
|
|
|
240
|
+
# Only if plugins.allow already contains an array, append hypercompositor and hypermem to that existing array.
|
|
241
|
+
# If plugins.allow is unset, null, or empty, skip the allowlist step.
|
|
242
|
+
|
|
243
|
+
openclaw gateway restart
|
|
244
|
+
EOF
|
|
494
245
|
echo ""
|
|
495
|
-
echo -e " ${
|
|
496
|
-
|
|
246
|
+
echo -e " ${BOLD}Verify:${NC}"
|
|
247
|
+
cat <<EOF
|
|
248
|
+
openclaw plugins list
|
|
249
|
+
openclaw logs --limit 100 | grep -E 'hypermem|context-engine|falling back'
|
|
250
|
+
node ${RUNTIME_DIR}/bin/hypermem-status.mjs --health
|
|
251
|
+
node ${RUNTIME_DIR}/bin/hypermem-model-audit.mjs --strict
|
|
252
|
+
EOF
|
|
497
253
|
echo ""
|
|
254
|
+
echo -e " ${DIM}A staged runtime is not active until OpenClaw is wired and restarted.${NC}"
|
|
498
255
|
}
|
|
499
256
|
|
|
500
|
-
# ─────────────────────────────────────────────
|
|
501
|
-
# Main
|
|
502
|
-
# ─────────────────────────────────────────────
|
|
503
257
|
main() {
|
|
504
258
|
banner
|
|
505
259
|
preflight
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
register_plugin
|
|
512
|
-
smoke_test
|
|
513
|
-
summary
|
|
260
|
+
install_package
|
|
261
|
+
stage_runtime
|
|
262
|
+
write_minimal_config_if_missing
|
|
263
|
+
verify_stage
|
|
264
|
+
next_steps
|
|
514
265
|
}
|
|
515
266
|
|
|
516
267
|
main "$@"
|