@gamaze/hicortex 0.3.10 → 0.3.12
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/init.js +3 -3
- package/dist/llm.d.ts +11 -0
- package/dist/llm.js +26 -1
- package/dist/mcp-server.js +53 -1
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
package/dist/init.js
CHANGED
|
@@ -331,7 +331,7 @@ async function persistLlmConfig() {
|
|
|
331
331
|
console.log(" How should Hicortex access an LLM?\n");
|
|
332
332
|
console.log(" 1. Use Claude subscription via CLI (Haiku model, no API key needed)");
|
|
333
333
|
console.log(" 2. Enter an API key manually (Anthropic, OpenAI, or other)");
|
|
334
|
-
console.log(" 3.
|
|
334
|
+
console.log(" 3. Cancel installation\n");
|
|
335
335
|
const choice = await ask(" Choice [1]: ");
|
|
336
336
|
const selected = choice === "2" ? 2 : choice === "3" ? 3 : 1;
|
|
337
337
|
if (selected === 1) {
|
|
@@ -353,8 +353,8 @@ async function persistLlmConfig() {
|
|
|
353
353
|
console.log(` ✓ API key saved`);
|
|
354
354
|
}
|
|
355
355
|
else {
|
|
356
|
-
console.log("
|
|
357
|
-
|
|
356
|
+
console.log("\n Hicortex requires an LLM to function. Installation cancelled.");
|
|
357
|
+
process.exit(0);
|
|
358
358
|
}
|
|
359
359
|
}
|
|
360
360
|
function saveConfig(configPath, config) {
|
package/dist/llm.d.ts
CHANGED
|
@@ -23,6 +23,12 @@ export interface LlmConfig {
|
|
|
23
23
|
model: string;
|
|
24
24
|
reflectModel: string;
|
|
25
25
|
provider: string;
|
|
26
|
+
/** Optional separate model for distillation (defaults to model if unset). */
|
|
27
|
+
distillModel?: string;
|
|
28
|
+
/** Optional separate endpoint for reflect-tier LLM (e.g. remote Ollama with larger model). */
|
|
29
|
+
reflectBaseUrl?: string;
|
|
30
|
+
reflectApiKey?: string;
|
|
31
|
+
reflectProvider?: string;
|
|
26
32
|
}
|
|
27
33
|
/**
|
|
28
34
|
* Resolve LLM configuration from plugin config, OpenClaw config, env vars, or Ollama fallback.
|
|
@@ -70,12 +76,17 @@ export declare class LlmClient {
|
|
|
70
76
|
completeFast(prompt: string, maxTokens?: number): Promise<string>;
|
|
71
77
|
/**
|
|
72
78
|
* Reflect-tier completion (nightly reflection, needs reasoning).
|
|
79
|
+
* Routes to reflectBaseUrl/reflectProvider if configured (e.g. remote Ollama with larger model).
|
|
73
80
|
*/
|
|
74
81
|
completeReflect(prompt: string, maxTokens?: number): Promise<string>;
|
|
75
82
|
/**
|
|
76
83
|
* Distillation-tier completion (session knowledge extraction).
|
|
77
84
|
*/
|
|
78
85
|
completeDistill(prompt: string, maxTokens?: number): Promise<string>;
|
|
86
|
+
/**
|
|
87
|
+
* Complete with overridden baseUrl/apiKey/provider (used for reflect tier with separate endpoint).
|
|
88
|
+
*/
|
|
89
|
+
private completeWithOverride;
|
|
79
90
|
private complete;
|
|
80
91
|
/**
|
|
81
92
|
* Claude CLI: shell out to `claude -p` for subscription users.
|
package/dist/llm.js
CHANGED
|
@@ -422,15 +422,40 @@ class LlmClient {
|
|
|
422
422
|
}
|
|
423
423
|
/**
|
|
424
424
|
* Reflect-tier completion (nightly reflection, needs reasoning).
|
|
425
|
+
* Routes to reflectBaseUrl/reflectProvider if configured (e.g. remote Ollama with larger model).
|
|
425
426
|
*/
|
|
426
427
|
async completeReflect(prompt, maxTokens = 8192) {
|
|
428
|
+
if (this.config.reflectBaseUrl) {
|
|
429
|
+
return this.completeWithOverride(this.config.reflectBaseUrl, this.config.reflectApiKey ?? this.config.apiKey, this.config.reflectProvider ?? this.config.provider, this.config.reflectModel, prompt, maxTokens, 900_000);
|
|
430
|
+
}
|
|
427
431
|
return this.complete(this.config.reflectModel, prompt, maxTokens, 900_000);
|
|
428
432
|
}
|
|
429
433
|
/**
|
|
430
434
|
* Distillation-tier completion (session knowledge extraction).
|
|
431
435
|
*/
|
|
432
436
|
async completeDistill(prompt, maxTokens = 2048) {
|
|
433
|
-
return this.complete(this.config.model, prompt, maxTokens, 900_000);
|
|
437
|
+
return this.complete(this.config.distillModel ?? this.config.model, prompt, maxTokens, 900_000);
|
|
438
|
+
}
|
|
439
|
+
/**
|
|
440
|
+
* Complete with overridden baseUrl/apiKey/provider (used for reflect tier with separate endpoint).
|
|
441
|
+
*/
|
|
442
|
+
async completeWithOverride(baseUrl, apiKey, provider, model, prompt, maxTokens, timeoutMs) {
|
|
443
|
+
if (this.isRateLimited) {
|
|
444
|
+
throw new RateLimitError(this.rateLimitedUntil - Date.now());
|
|
445
|
+
}
|
|
446
|
+
// Temporarily swap config for this call
|
|
447
|
+
const saved = { baseUrl: this.config.baseUrl, apiKey: this.config.apiKey, provider: this.config.provider };
|
|
448
|
+
this.config.baseUrl = baseUrl;
|
|
449
|
+
this.config.apiKey = apiKey;
|
|
450
|
+
this.config.provider = provider;
|
|
451
|
+
try {
|
|
452
|
+
return await this.complete(model, prompt, maxTokens, timeoutMs);
|
|
453
|
+
}
|
|
454
|
+
finally {
|
|
455
|
+
this.config.baseUrl = saved.baseUrl;
|
|
456
|
+
this.config.apiKey = saved.apiKey;
|
|
457
|
+
this.config.provider = saved.provider;
|
|
458
|
+
}
|
|
434
459
|
}
|
|
435
460
|
async complete(model, prompt, maxTokens, timeoutMs) {
|
|
436
461
|
if (this.isRateLimited) {
|
package/dist/mcp-server.js
CHANGED
|
@@ -197,10 +197,25 @@ async function startServer(options = {}) {
|
|
|
197
197
|
llmBaseUrl: savedConfig?.llmBaseUrl,
|
|
198
198
|
llmApiKey: savedConfig?.llmApiKey,
|
|
199
199
|
llmModel: savedConfig?.llmModel,
|
|
200
|
+
reflectModel: savedConfig?.reflectModel,
|
|
200
201
|
});
|
|
201
202
|
}
|
|
203
|
+
// Apply optional distillModel (e.g. larger local model for session extraction)
|
|
204
|
+
if (savedConfig?.distillModel) {
|
|
205
|
+
llmConfig.distillModel = savedConfig.distillModel;
|
|
206
|
+
}
|
|
207
|
+
// Apply separate reflect endpoint if configured (e.g. remote Ollama with larger model)
|
|
208
|
+
if (savedConfig?.reflectBaseUrl) {
|
|
209
|
+
llmConfig.reflectBaseUrl = savedConfig.reflectBaseUrl;
|
|
210
|
+
llmConfig.reflectApiKey = savedConfig.reflectApiKey ?? llmConfig.apiKey;
|
|
211
|
+
llmConfig.reflectProvider = savedConfig.reflectProvider ?? llmConfig.provider;
|
|
212
|
+
}
|
|
202
213
|
llm = new llm_js_1.LlmClient(llmConfig);
|
|
203
|
-
|
|
214
|
+
const distillInfo = llmConfig.distillModel ? `, distill: ${llmConfig.distillModel}` : "";
|
|
215
|
+
const reflectInfo = llmConfig.reflectBaseUrl
|
|
216
|
+
? `${llmConfig.reflectProvider}/${llmConfig.reflectModel}@${llmConfig.reflectBaseUrl}`
|
|
217
|
+
: llmConfig.reflectModel;
|
|
218
|
+
console.log(`[hicortex] LLM fast: ${llmConfig.provider}/${llmConfig.model}${distillInfo}, reflect: ${reflectInfo}`);
|
|
204
219
|
// License: read from options, config file, or env var
|
|
205
220
|
const licenseKey = options.licenseKey
|
|
206
221
|
?? savedConfig?.licenseKey
|
|
@@ -220,9 +235,46 @@ async function startServer(options = {}) {
|
|
|
220
235
|
const stats = (0, db_js_1.getStats)(db, dbPath);
|
|
221
236
|
console.log(`[hicortex] Ready: ${stats.memories} memories, ${stats.links} links, ` +
|
|
222
237
|
`${Math.round(stats.db_size_bytes / 1024)} KB`);
|
|
238
|
+
// Auth token: from options, config file, or env var
|
|
239
|
+
const authToken = savedConfig?.authToken
|
|
240
|
+
?? process.env.HICORTEX_AUTH_TOKEN
|
|
241
|
+
?? "";
|
|
223
242
|
// Express app
|
|
224
243
|
const app = (0, express_1.default)();
|
|
225
244
|
app.use(express_1.default.json());
|
|
245
|
+
// Optional bearer token auth (skip for /health and localhost when no token)
|
|
246
|
+
if (authToken) {
|
|
247
|
+
console.log(`[hicortex] Bearer token auth enabled`);
|
|
248
|
+
app.use((req, res, next) => {
|
|
249
|
+
// Always allow health endpoint
|
|
250
|
+
if (req.path === "/health")
|
|
251
|
+
return next();
|
|
252
|
+
// Allow localhost without auth
|
|
253
|
+
const ip = req.ip ?? req.socket.remoteAddress ?? "";
|
|
254
|
+
if (ip === "127.0.0.1" || ip === "::1" || ip === "::ffff:127.0.0.1")
|
|
255
|
+
return next();
|
|
256
|
+
// Check bearer token
|
|
257
|
+
const auth = req.headers.authorization;
|
|
258
|
+
if (auth === `Bearer ${authToken}`)
|
|
259
|
+
return next();
|
|
260
|
+
res.status(401).json({ error: "Unauthorized" });
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
// CORS: allow Claude Desktop (https://claude.ai) and other browser-based MCP clients
|
|
264
|
+
app.use((req, res, next) => {
|
|
265
|
+
const origin = req.headers.origin;
|
|
266
|
+
if (origin) {
|
|
267
|
+
res.setHeader("Access-Control-Allow-Origin", origin);
|
|
268
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
269
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, Authorization");
|
|
270
|
+
res.setHeader("Access-Control-Allow-Credentials", "true");
|
|
271
|
+
}
|
|
272
|
+
if (req.method === "OPTIONS") {
|
|
273
|
+
res.status(204).end();
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
next();
|
|
277
|
+
});
|
|
226
278
|
// SSE transport management — each connection gets its own McpServer instance
|
|
227
279
|
const transports = new Map();
|
|
228
280
|
// Health endpoint
|
package/openclaw.plugin.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"id": "hicortex",
|
|
3
3
|
"name": "Hicortex — Long-term Memory That Learns",
|
|
4
4
|
"description": "Your agents remember past decisions, avoid repeated mistakes, and get smarter every day. Nightly reflection generates actionable lessons that automatically update agent behavior.",
|
|
5
|
-
"version": "0.3.
|
|
5
|
+
"version": "0.3.11",
|
|
6
6
|
"kind": "lifecycle",
|
|
7
7
|
"skills": ["./skills/hicortex-memory", "./skills/hicortex-learn", "./skills/hicortex-activate"],
|
|
8
8
|
"configSchema": {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gamaze/hicortex",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.12",
|
|
4
4
|
"description": "Human-like memory for self-improving AI agents. Automatic capturing, nightly reflection, and cross-agent learning. Works with Claude Code and OpenClaw.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|