@cybermem/cli 0.6.11 → 0.7.7
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/commands/backup.js +3 -3
- package/dist/commands/dashboard.js +90 -0
- package/dist/commands/init.js +231 -47
- package/dist/commands/login.js +165 -0
- package/dist/commands/reset.js +1 -1
- package/dist/commands/restore.js +4 -4
- package/dist/commands/upgrade.js +141 -0
- package/dist/index.js +39 -18
- package/dist/templates/auth-sidecar/server.js +54 -2
- package/dist/templates/docker-compose.yml +57 -65
- package/dist/templates/envs/local.env +17 -0
- package/dist/templates/envs/rpi-tailscale.env +23 -0
- package/dist/templates/envs/rpi.env +22 -0
- package/dist/templates/envs/vps.env +29 -0
- package/dist/templates/monitoring/db_exporter/exporter.py +9 -4
- package/package.json +7 -1
- package/templates/auth-sidecar/server.js +54 -2
- package/templates/docker-compose.yml +57 -65
- package/templates/envs/local.env +17 -0
- package/templates/envs/rpi-tailscale.env +23 -0
- package/templates/envs/rpi.env +22 -0
- package/templates/envs/vps.env +29 -0
- package/templates/monitoring/db_exporter/exporter.py +9 -4
- package/templates/envs/local.example +0 -27
- package/templates/envs/rpi.example +0 -27
- package/templates/envs/vps.example +0 -25
|
@@ -97,7 +97,7 @@ function isLocalRequest(req) {
|
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// ForwardAuth handler
|
|
100
|
-
const server = http.createServer((req, res) => {
|
|
100
|
+
const server = http.createServer(async (req, res) => {
|
|
101
101
|
// Health check
|
|
102
102
|
if (req.url === "/health") {
|
|
103
103
|
res.writeHead(200, { "Content-Type": "application/json" });
|
|
@@ -108,9 +108,22 @@ const server = http.createServer((req, res) => {
|
|
|
108
108
|
const authHeader = req.headers["authorization"];
|
|
109
109
|
const apiKeyHeader = req.headers["x-api-key"];
|
|
110
110
|
|
|
111
|
-
// 1. Check
|
|
111
|
+
// 1. Check Bearer token (JWT or API Key)
|
|
112
112
|
if (authHeader?.startsWith("Bearer ")) {
|
|
113
113
|
const token = authHeader.substring(7);
|
|
114
|
+
|
|
115
|
+
// 1a. Check if Bearer token is actually an API key (MCP clients like Claude Desktop)
|
|
116
|
+
const expectedKey = loadApiKey();
|
|
117
|
+
if (expectedKey && token === expectedKey) {
|
|
118
|
+
console.log("Auth OK: Bearer API Key");
|
|
119
|
+
res.writeHead(200, {
|
|
120
|
+
"X-Auth-Method": "bearer-api-key",
|
|
121
|
+
});
|
|
122
|
+
res.end();
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// 1b. Try JWT RS256 validation
|
|
114
127
|
const payload = validateJwt(token);
|
|
115
128
|
|
|
116
129
|
if (payload) {
|
|
@@ -124,6 +137,45 @@ const server = http.createServer((req, res) => {
|
|
|
124
137
|
res.end();
|
|
125
138
|
return;
|
|
126
139
|
}
|
|
140
|
+
|
|
141
|
+
// 1c. Try GitHub OAuth token verification
|
|
142
|
+
try {
|
|
143
|
+
const https = require("https");
|
|
144
|
+
const ghRes = await new Promise((resolve, reject) => {
|
|
145
|
+
const req = https.get(
|
|
146
|
+
"https://api.github.com/user",
|
|
147
|
+
{
|
|
148
|
+
headers: {
|
|
149
|
+
Authorization: `Bearer ${token}`,
|
|
150
|
+
"User-Agent": "CyberMem-Auth-Sidecar/1.0",
|
|
151
|
+
Accept: "application/vnd.github+json",
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
(res) => {
|
|
155
|
+
let data = "";
|
|
156
|
+
res.on("data", (chunk) => (data += chunk));
|
|
157
|
+
res.on("end", () => resolve({ status: res.statusCode, data }));
|
|
158
|
+
},
|
|
159
|
+
);
|
|
160
|
+
req.on("error", reject);
|
|
161
|
+
req.end();
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
if (ghRes.status === 200) {
|
|
165
|
+
const user = JSON.parse(ghRes.data);
|
|
166
|
+
console.log(`Auth OK: GitHub OAuth (${user.login})`);
|
|
167
|
+
res.writeHead(200, {
|
|
168
|
+
"X-User-Id": String(user.id),
|
|
169
|
+
"X-User-Email": user.email || "",
|
|
170
|
+
"X-User-Name": user.login,
|
|
171
|
+
"X-Auth-Method": "github-oauth",
|
|
172
|
+
});
|
|
173
|
+
res.end();
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
} catch (err) {
|
|
177
|
+
// GitHub verification failed, continue to other methods
|
|
178
|
+
}
|
|
127
179
|
}
|
|
128
180
|
|
|
129
181
|
// 2. Check API Key (deprecated fallback)
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# yaml-language-server: $schema=https://raw.githubusercontent.com/compose-spec/compose-spec/master/schema/compose-spec.json
|
|
1
2
|
# CyberMem - OpenMemory + DevOps monitoring stack
|
|
2
3
|
# For local development only
|
|
3
4
|
# Production deployment: use Helm chart (charts/cybermem/)
|
|
@@ -24,21 +25,53 @@ services:
|
|
|
24
25
|
- traefik-logs:/var/log/traefik
|
|
25
26
|
labels:
|
|
26
27
|
- traefik.enable=true
|
|
28
|
+
- traefik.http.middlewares.auth-check.forwardauth.address=http://auth-sidecar:3001/auth
|
|
29
|
+
- traefik.http.middlewares.auth-check.forwardauth.authResponseHeaders=X-User-Id,X-User-Email,X-User-Name,X-Auth-Method
|
|
27
30
|
restart: unless-stopped
|
|
28
31
|
|
|
29
|
-
#
|
|
30
|
-
mcp-
|
|
32
|
+
# MCP Server (Node.js/SDK)
|
|
33
|
+
mcp-server:
|
|
31
34
|
build:
|
|
32
|
-
context:
|
|
35
|
+
context: ../../mcp
|
|
33
36
|
dockerfile: Dockerfile
|
|
34
|
-
|
|
37
|
+
image: ghcr.io/mikhailkogan17/cybermem-mcp:latest
|
|
38
|
+
# Note: platform omitted - docker auto-detects (amd64 for CI, arm64 for RPi)
|
|
39
|
+
restart: unless-stopped
|
|
40
|
+
container_name: cybermem-mcp
|
|
41
|
+
environment:
|
|
42
|
+
OM_TIER: "hybrid"
|
|
43
|
+
PORT: "8080"
|
|
44
|
+
OM_PORT: "0"
|
|
45
|
+
OM_DB_PATH: /data/openmemory.sqlite
|
|
46
|
+
volumes:
|
|
47
|
+
- ${CYBERMEM_ENV_PATH:-${HOME}/.cybermem/.env}:/.env
|
|
48
|
+
- ${HOME}/.cybermem/data:/data
|
|
49
|
+
depends_on:
|
|
50
|
+
- traefik
|
|
51
|
+
- auth-sidecar
|
|
35
52
|
labels:
|
|
36
53
|
- traefik.enable=true
|
|
37
|
-
|
|
38
|
-
- traefik.http.
|
|
39
|
-
|
|
40
|
-
- traefik.http.
|
|
41
|
-
|
|
54
|
+
# Middleware definitions (must be on a service that starts BEFORE routes reference them)
|
|
55
|
+
- traefik.http.middlewares.strip-cybermem.stripprefix.prefixes=/cybermem
|
|
56
|
+
# Authenticated routes
|
|
57
|
+
- traefik.http.routers.mcp.rule=PathPrefix(`/cybermem/mcp`) || PathPrefix(`/cybermem/sse`) || PathPrefix(`/mcp`) || PathPrefix(`/sse`)
|
|
58
|
+
- traefik.http.routers.mcp.entrypoints=web
|
|
59
|
+
- traefik.http.routers.mcp.priority=100
|
|
60
|
+
- traefik.http.routers.mcp.service=mcp-service
|
|
61
|
+
- traefik.http.routers.mcp.middlewares=auth-check,strip-cybermem
|
|
62
|
+
# Public routes (Health/Metrics)
|
|
63
|
+
- traefik.http.routers.mcp-public.rule=PathPrefix(`/cybermem/health`) || PathPrefix(`/cybermem/metrics`) || PathPrefix(`/health`) || PathPrefix(`/metrics`)
|
|
64
|
+
- traefik.http.routers.mcp-public.entrypoints=web
|
|
65
|
+
- traefik.http.routers.mcp-public.priority=100
|
|
66
|
+
- traefik.http.routers.mcp-public.service=mcp-service
|
|
67
|
+
- traefik.http.routers.mcp-public.middlewares=strip-cybermem
|
|
68
|
+
- traefik.http.services.mcp-service.loadbalancer.server.port=8080
|
|
69
|
+
# Legacy API support (for simple REST clients)
|
|
70
|
+
- traefik.http.routers.legacy-api.rule=PathPrefix(`/cybermem/add`) || PathPrefix(`/cybermem/query`) || PathPrefix(`/cybermem/all`) || PathPrefix(`/add`) || PathPrefix(`/query`) || PathPrefix(`/all`)
|
|
71
|
+
- traefik.http.routers.legacy-api.entrypoints=web
|
|
72
|
+
- traefik.http.routers.legacy-api.priority=100
|
|
73
|
+
- traefik.http.routers.legacy-api.service=mcp-service
|
|
74
|
+
- traefik.http.routers.legacy-api.middlewares=auth-check,strip-cybermem
|
|
42
75
|
|
|
43
76
|
# Auth sidecar for JWT/API key validation (ForwardAuth)
|
|
44
77
|
auth-sidecar:
|
|
@@ -48,12 +81,9 @@ services:
|
|
|
48
81
|
PORT: "3001"
|
|
49
82
|
API_KEY_FILE: /.env
|
|
50
83
|
volumes:
|
|
51
|
-
- ${CYBERMEM_ENV_PATH}:/.env:ro
|
|
84
|
+
- ${CYBERMEM_ENV_PATH:-${HOME}/.cybermem/.env}:/.env:ro
|
|
52
85
|
labels:
|
|
53
86
|
- traefik.enable=true
|
|
54
|
-
# ForwardAuth middleware
|
|
55
|
-
- traefik.http.middlewares.auth-check.forwardauth.address=http://auth-sidecar:3001/auth
|
|
56
|
-
- traefik.http.middlewares.auth-check.forwardauth.authResponseHeaders=X-User-Id,X-User-Email,X-User-Name,X-Auth-Method
|
|
57
87
|
healthcheck:
|
|
58
88
|
test:
|
|
59
89
|
[
|
|
@@ -69,9 +99,8 @@ services:
|
|
|
69
99
|
retries: 3
|
|
70
100
|
restart: unless-stopped
|
|
71
101
|
|
|
72
|
-
#
|
|
73
|
-
#
|
|
74
|
-
# SQLite stored at ~/.cybermem/data/openmemory.sqlite
|
|
102
|
+
# Memory engine (MCP + Persistence)
|
|
103
|
+
# Uses embedded SQLite stored at ~/.cybermem/data/openmemory.sqlite
|
|
75
104
|
|
|
76
105
|
db-exporter:
|
|
77
106
|
image: ghcr.io/mikhailkogan17/cybermem-db_exporter:latest
|
|
@@ -84,7 +113,7 @@ services:
|
|
|
84
113
|
- "8000:8000"
|
|
85
114
|
volumes:
|
|
86
115
|
# Mount host openmemory data dir (created by SDK)
|
|
87
|
-
- ${HOME}/.cybermem/data:/data
|
|
116
|
+
- ${HOME}/.cybermem/data:/data
|
|
88
117
|
restart: unless-stopped
|
|
89
118
|
|
|
90
119
|
log-exporter:
|
|
@@ -97,7 +126,7 @@ services:
|
|
|
97
126
|
DB_PATH: /data/openmemory.sqlite
|
|
98
127
|
volumes:
|
|
99
128
|
- traefik-logs:/var/log/traefik:ro
|
|
100
|
-
- ${HOME}/.cybermem/data:/data
|
|
129
|
+
- ${HOME}/.cybermem/data:/data
|
|
101
130
|
- ./monitoring/log_exporter/exporter.py:/app/exporter.py:ro
|
|
102
131
|
restart: unless-stopped
|
|
103
132
|
depends_on:
|
|
@@ -123,22 +152,6 @@ services:
|
|
|
123
152
|
profiles:
|
|
124
153
|
- postgres
|
|
125
154
|
|
|
126
|
-
postgres-exporter:
|
|
127
|
-
image: prometheuscommunity/postgres-exporter:v0.15.0
|
|
128
|
-
container_name: cybermem-postgres-exporter
|
|
129
|
-
environment:
|
|
130
|
-
DATA_SOURCE_NAME: postgresql://${PG_USER:-openmemory}:${PG_PASSWORD:-postgres}@postgres:5432/${PG_DB:-openmemory}?sslmode=disable
|
|
131
|
-
PG_EXPORTER_EXTEND_QUERY_PATH: /queries.yml
|
|
132
|
-
ports:
|
|
133
|
-
- "9187:9187"
|
|
134
|
-
volumes:
|
|
135
|
-
- ./monitoring/postgres_exporter/queries.yml:/queries.yml:ro
|
|
136
|
-
restart: unless-stopped
|
|
137
|
-
depends_on:
|
|
138
|
-
- postgres
|
|
139
|
-
profiles:
|
|
140
|
-
- postgres
|
|
141
|
-
|
|
142
155
|
ollama:
|
|
143
156
|
image: ollama/ollama:latest
|
|
144
157
|
container_name: cybermem-ollama
|
|
@@ -150,55 +163,37 @@ services:
|
|
|
150
163
|
profiles:
|
|
151
164
|
- ollama
|
|
152
165
|
|
|
153
|
-
prometheus:
|
|
154
|
-
image: prom/prometheus:v2.48.0
|
|
155
|
-
container_name: cybermem-prometheus
|
|
156
|
-
command:
|
|
157
|
-
- --config.file=/etc/prometheus/prometheus.yml
|
|
158
|
-
- --storage.tsdb.path=/prometheus
|
|
159
|
-
- --storage.tsdb.retention.time=${PROM_RETENTION:-7d}
|
|
160
|
-
- --web.console.libraries=/usr/share/prometheus/console_libraries
|
|
161
|
-
- --web.console.templates=/usr/share/prometheus/consoles
|
|
162
|
-
ports:
|
|
163
|
-
- "9092:9090"
|
|
164
|
-
volumes:
|
|
165
|
-
- ./monitoring/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
|
166
|
-
- prometheus-data:/prometheus
|
|
167
|
-
restart: unless-stopped
|
|
168
|
-
depends_on:
|
|
169
|
-
- db-exporter
|
|
170
|
-
|
|
171
166
|
dashboard:
|
|
172
167
|
image: ghcr.io/mikhailkogan17/cybermem-dashboard:latest
|
|
168
|
+
# Note: platform omitted - docker auto-detects (amd64 for CI, arm64 for RPi)
|
|
173
169
|
container_name: cybermem-dashboard
|
|
174
170
|
environment:
|
|
175
171
|
DB_EXPORTER_URL: http://db-exporter:8000
|
|
176
|
-
|
|
177
|
-
|
|
172
|
+
# Required for Health Check to find the MCP API internally
|
|
173
|
+
CYBERMEM_URL: http://mcp-server:8080
|
|
174
|
+
OM_DB_PATH: /data/openmemory.sqlite
|
|
178
175
|
OM_API_KEY: ${OM_API_KEY:-dev-secret-key}
|
|
179
|
-
# WATCHPACK_POLLING: "true" # Enable if hot reload blocks (high CPU usage)
|
|
180
176
|
ports:
|
|
181
177
|
- "3000:3000"
|
|
182
178
|
volumes:
|
|
183
|
-
-
|
|
179
|
+
- ${HOME}/.cybermem/data:/data
|
|
184
180
|
- /var/run/docker.sock:/var/run/docker.sock
|
|
185
|
-
- ${CYBERMEM_ENV_PATH}:/app/shared.env
|
|
181
|
+
- ${CYBERMEM_ENV_PATH:-${HOME}/.cybermem/.env}:/app/shared.env
|
|
186
182
|
labels:
|
|
187
183
|
- traefik.enable=true
|
|
188
184
|
# Dashboard route: /cybermem -> dashboard on port 3000
|
|
189
185
|
- traefik.http.routers.dashboard.entrypoints=web
|
|
190
|
-
- traefik.http.routers.dashboard.rule=PathPrefix(`/cybermem`)
|
|
191
|
-
- traefik.http.routers.dashboard.
|
|
192
|
-
- traefik.http.middlewares
|
|
186
|
+
- traefik.http.routers.dashboard.rule=PathPrefix(`/cybermem`) && !PathPrefix(`/cybermem/mcp`) && !PathPrefix(`/cybermem/health`)
|
|
187
|
+
- traefik.http.routers.dashboard.priority=10
|
|
188
|
+
- traefik.http.routers.dashboard.middlewares=auth-check,strip-cybermem
|
|
193
189
|
- traefik.http.services.dashboard.loadbalancer.server.port=3000
|
|
194
190
|
restart: unless-stopped
|
|
195
191
|
depends_on:
|
|
196
|
-
- prometheus
|
|
197
192
|
- db-exporter
|
|
198
193
|
|
|
199
194
|
volumes:
|
|
200
195
|
openmemory-data:
|
|
201
|
-
name: cybermem-
|
|
196
|
+
name: cybermem-data
|
|
202
197
|
driver: local
|
|
203
198
|
postgres-data:
|
|
204
199
|
name: cybermem-postgres-data
|
|
@@ -206,9 +201,6 @@ volumes:
|
|
|
206
201
|
ollama-models:
|
|
207
202
|
name: cybermem-ollama-models
|
|
208
203
|
driver: local
|
|
209
|
-
prometheus-data:
|
|
210
|
-
name: cybermem-prometheus-data
|
|
211
|
-
driver: local
|
|
212
204
|
traefik-logs:
|
|
213
205
|
name: cybermem-traefik-logs
|
|
214
206
|
driver: local
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Environment: LOCAL (Dev)
|
|
2
|
+
# No API key required for localhost access.
|
|
3
|
+
# Used by: npx @cybermem/cli init --local
|
|
4
|
+
|
|
5
|
+
# Application Settings
|
|
6
|
+
LOG_LEVEL=info
|
|
7
|
+
NEXT_PUBLIC_APP_URL=http://localhost:3000
|
|
8
|
+
|
|
9
|
+
# Database (SQLite)
|
|
10
|
+
# OM_DB_PATH is mounted to /data/openmemory.sqlite in Docker
|
|
11
|
+
|
|
12
|
+
# Security
|
|
13
|
+
# OM_API_KEY is intentionally empty for local development to bypass auth.
|
|
14
|
+
OM_API_KEY=
|
|
15
|
+
|
|
16
|
+
# Optional: Add your OpenAI Key if using cloud embeddings
|
|
17
|
+
# OPENAI_API_KEY=
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# Environment: RPi + Tailscale (Remote Access)
|
|
2
|
+
# Secured via Tailscale Funnel.
|
|
3
|
+
# Used by: npx @cybermem/cli init --rpi --remote-access
|
|
4
|
+
|
|
5
|
+
# Application Settings
|
|
6
|
+
LOG_LEVEL=info
|
|
7
|
+
|
|
8
|
+
# Database (SQLite)
|
|
9
|
+
# OM_DB_PATH is mounted to /data/openmemory.sqlite in Docker
|
|
10
|
+
|
|
11
|
+
# Security
|
|
12
|
+
# GENERATED AUTOMATICALLY BY CLI
|
|
13
|
+
OM_API_KEY=
|
|
14
|
+
|
|
15
|
+
# Tailscale Configuration
|
|
16
|
+
# Ensure "tailscale serve" is running (handled by CLI)
|
|
17
|
+
TS_HOSTNAME=raspberrypi
|
|
18
|
+
|
|
19
|
+
# Dashboard
|
|
20
|
+
NEXT_PUBLIC_APP_URL=https://raspberrypi.tailnet-name.ts.net
|
|
21
|
+
|
|
22
|
+
# Optional: Local LLM
|
|
23
|
+
OLLAMA_URL=http://ollama:11434
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Environment: RPi (Local Network)
|
|
2
|
+
# Internal API key required.
|
|
3
|
+
# Used by: npx @cybermem/cli init --rpi
|
|
4
|
+
|
|
5
|
+
# Application Settings
|
|
6
|
+
LOG_LEVEL=info
|
|
7
|
+
|
|
8
|
+
# Database (SQLite)
|
|
9
|
+
# OM_DB_PATH is mounted to /data/openmemory.sqlite in Docker
|
|
10
|
+
|
|
11
|
+
# Security
|
|
12
|
+
# GENERATED AUTOMATICALLY BY CLI
|
|
13
|
+
# DO NOT SHARE THIS KEY. It is for internal service communication.
|
|
14
|
+
OM_API_KEY=
|
|
15
|
+
|
|
16
|
+
# Dashboard
|
|
17
|
+
# Clients connecting via MCP must use OAuth or this key (if configured for direct access).
|
|
18
|
+
# OAUTH_CLIENT_ID=...
|
|
19
|
+
# OAUTH_CLIENT_SECRET=...
|
|
20
|
+
|
|
21
|
+
# Optional: Local LLM
|
|
22
|
+
OLLAMA_URL=http://ollama:11434
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Environment: VPS (Public Cloud)
|
|
2
|
+
# High security setup.
|
|
3
|
+
# Used by: npx @cybermem/cli init --vps
|
|
4
|
+
|
|
5
|
+
# Application Settings
|
|
6
|
+
LOG_LEVEL=warn
|
|
7
|
+
# Set your domain here
|
|
8
|
+
NEXT_PUBLIC_APP_URL=https://cybermem.yourdomain.com
|
|
9
|
+
|
|
10
|
+
# Database (PostgreSQL recommended for VPS, but SQLite default)
|
|
11
|
+
# To use Postgres:
|
|
12
|
+
# DB_TYPE=postgres
|
|
13
|
+
# POSTGRES_URL=postgresql://user:pass@db:5432/cybermem
|
|
14
|
+
|
|
15
|
+
# Security
|
|
16
|
+
# GENERATED AUTOMATICALLY BY CLI
|
|
17
|
+
OM_API_KEY=
|
|
18
|
+
|
|
19
|
+
# Auth Sidecar (JWT)
|
|
20
|
+
# Generate a random secret: openssl rand -hex 32
|
|
21
|
+
JWT_SECRET=
|
|
22
|
+
JWT_PRIVATE_KEY=
|
|
23
|
+
|
|
24
|
+
# GitHub OAuth (Recommended for dashboard access)
|
|
25
|
+
OAUTH_CLIENT_ID=
|
|
26
|
+
OAUTH_CLIENT_SECRET=
|
|
27
|
+
|
|
28
|
+
# OpenAI (Recommended for VPS performance)
|
|
29
|
+
OPENAI_API_KEY=
|
|
@@ -123,11 +123,16 @@ def collect_metrics():
|
|
|
123
123
|
FROM memories
|
|
124
124
|
GROUP BY user_id
|
|
125
125
|
""")
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
126
|
+
rows = cursor.fetchall()
|
|
127
|
+
if not rows:
|
|
128
|
+
# Emit a default anonymous:0 if no data
|
|
129
|
+
memories_total.labels(client="anonymous").set(0)
|
|
130
|
+
else:
|
|
131
|
+
for row in rows:
|
|
132
|
+
client = row["client"] or "anonymous"
|
|
133
|
+
memories_total.labels(client=client).set(row["count"])
|
|
129
134
|
|
|
130
|
-
logger.debug(f"Collected total memories for {
|
|
135
|
+
logger.debug(f"Collected total memories for {len(rows)} clients")
|
|
131
136
|
|
|
132
137
|
# Metric 2: Recent memories (24h)
|
|
133
138
|
# Note: created_at is stored as milliseconds since epoch
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Example environment configuration
|
|
2
|
-
# Copy to .env and customize
|
|
3
|
-
|
|
4
|
-
# Embeddings provider: ollama (local) or openai (cloud)
|
|
5
|
-
EMBEDDINGS_PROVIDER=ollama
|
|
6
|
-
OLLAMA_URL=http://ollama:11434
|
|
7
|
-
OPENAI_API_KEY=
|
|
8
|
-
|
|
9
|
-
# Database backend: sqlite (local/rpi) or postgres (vps)
|
|
10
|
-
DB_BACKEND=sqlite
|
|
11
|
-
DB_PATH=/data/openmemory.sqlite
|
|
12
|
-
VECTOR_BACKEND=sqlite
|
|
13
|
-
|
|
14
|
-
# PostgreSQL settings (only for DB_BACKEND=postgres)
|
|
15
|
-
PG_HOST=postgres
|
|
16
|
-
PG_PORT=5432
|
|
17
|
-
PG_DB=openmemory
|
|
18
|
-
PG_USER=openmemory
|
|
19
|
-
PG_PASSWORD=change-me
|
|
20
|
-
|
|
21
|
-
# OpenMemory API key (Optional for local mode)
|
|
22
|
-
# OM_API_KEY=
|
|
23
|
-
|
|
24
|
-
# Monitoring
|
|
25
|
-
PROM_RETENTION=7d
|
|
26
|
-
GRAFANA_USER=admin
|
|
27
|
-
GRAFANA_PASSWORD=admin
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
# Raspberry Pi environment
|
|
2
|
-
# Optimized for low memory (1GB total)
|
|
3
|
-
DOCKER_PLATFORM=linux/arm64
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
# Embeddings (use Ollama with small models)
|
|
7
|
-
EMBEDDINGS_PROVIDER=ollama
|
|
8
|
-
OLLAMA_URL=http://ollama:11434
|
|
9
|
-
OPENAI_API_KEY=
|
|
10
|
-
|
|
11
|
-
# Database (SQLite for RPi - low memory footprint)
|
|
12
|
-
DB_BACKEND=sqlite
|
|
13
|
-
DB_PATH=/data/openmemory.sqlite
|
|
14
|
-
|
|
15
|
-
# PostgreSQL (not used)
|
|
16
|
-
PG_HOST=postgres
|
|
17
|
-
PG_DB=openmemory
|
|
18
|
-
PG_USER=openmemory
|
|
19
|
-
PG_PASSWORD=not-used
|
|
20
|
-
|
|
21
|
-
# OpenMemory
|
|
22
|
-
OM_API_KEY=key-change-me
|
|
23
|
-
|
|
24
|
-
# Monitoring (short retention for disk space)
|
|
25
|
-
PROM_RETENTION=3d
|
|
26
|
-
GRAFANA_USER=admin
|
|
27
|
-
GRAFANA_PASSWORD=admin
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
# VPS production environment
|
|
2
|
-
# For Hetzner CX22 or similar (2 vCPU, 4GB RAM)
|
|
3
|
-
|
|
4
|
-
# Embeddings (use OpenAI for production)
|
|
5
|
-
EMBEDDINGS_PROVIDER=openai
|
|
6
|
-
OPENAI_API_KEY=sk-change-me-in-production
|
|
7
|
-
OLLAMA_URL=
|
|
8
|
-
|
|
9
|
-
# Database (PostgreSQL for production)
|
|
10
|
-
DB_BACKEND=postgres
|
|
11
|
-
VECTOR_BACKEND=postgres
|
|
12
|
-
|
|
13
|
-
# PostgreSQL
|
|
14
|
-
PG_HOST=postgres
|
|
15
|
-
PG_DB=openmemory
|
|
16
|
-
PG_USER=openmemory
|
|
17
|
-
PG_PASSWORD=change-me-in-production-use-secrets
|
|
18
|
-
|
|
19
|
-
# OpenMemory
|
|
20
|
-
OM_API_KEY=change-me-in-production-use-secrets
|
|
21
|
-
|
|
22
|
-
# Monitoring
|
|
23
|
-
PROM_RETENTION=30d
|
|
24
|
-
GRAFANA_USER=admin
|
|
25
|
-
GRAFANA_PASSWORD=change-me-in-production-use-secrets
|