@usecortex_ai/openclaw-cortex-ai 0.1.1 → 0.1.2
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/commands/onboarding.ts +94 -66
- package/config.ts +27 -1
- package/index.ts +139 -5
- package/package.json +1 -1
package/commands/onboarding.ts
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
|
+
import * as fs from "node:fs"
|
|
2
|
+
import * as path from "node:path"
|
|
1
3
|
import * as readline from "node:readline"
|
|
2
4
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
|
|
3
5
|
import type { CortexClient } from "../client.ts"
|
|
4
6
|
import type { CortexPluginConfig } from "../config.ts"
|
|
5
7
|
import { log } from "../log.ts"
|
|
6
8
|
|
|
9
|
+
// ── Defaults (used when config is not yet available) ──
|
|
10
|
+
|
|
11
|
+
const DEFAULTS = {
|
|
12
|
+
subTenantId: "cortex-openclaw-plugin",
|
|
13
|
+
ignoreTerm: "cortex-ignore",
|
|
14
|
+
autoRecall: true,
|
|
15
|
+
autoCapture: true,
|
|
16
|
+
maxRecallResults: 10,
|
|
17
|
+
recallMode: "fast" as const,
|
|
18
|
+
graphContext: true,
|
|
19
|
+
debug: false,
|
|
20
|
+
}
|
|
21
|
+
|
|
7
22
|
// ── ANSI helpers ──
|
|
8
23
|
|
|
9
24
|
const c = {
|
|
@@ -160,57 +175,71 @@ type WizardResult = {
|
|
|
160
175
|
debug?: boolean
|
|
161
176
|
}
|
|
162
177
|
|
|
163
|
-
function
|
|
178
|
+
function buildConfigObj(result: WizardResult): Record<string, unknown> {
|
|
164
179
|
const obj: Record<string, unknown> = {}
|
|
165
180
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
if (result.
|
|
170
|
-
obj.tenantId = result.tenantId
|
|
171
|
-
}
|
|
172
|
-
if (result.subTenantId !== "cortex-openclaw-plugin") {
|
|
181
|
+
obj.apiKey = result.apiKey
|
|
182
|
+
obj.tenantId = result.tenantId
|
|
183
|
+
|
|
184
|
+
if (result.subTenantId !== DEFAULTS.subTenantId) {
|
|
173
185
|
obj.subTenantId = result.subTenantId
|
|
174
186
|
}
|
|
175
|
-
if (result.ignoreTerm !==
|
|
187
|
+
if (result.ignoreTerm !== DEFAULTS.ignoreTerm) {
|
|
176
188
|
obj.ignoreTerm = result.ignoreTerm
|
|
177
189
|
}
|
|
178
|
-
if (result.autoRecall !== undefined && result.autoRecall !==
|
|
190
|
+
if (result.autoRecall !== undefined && result.autoRecall !== DEFAULTS.autoRecall) {
|
|
179
191
|
obj.autoRecall = result.autoRecall
|
|
180
192
|
}
|
|
181
|
-
if (result.autoCapture !== undefined && result.autoCapture !==
|
|
193
|
+
if (result.autoCapture !== undefined && result.autoCapture !== DEFAULTS.autoCapture) {
|
|
182
194
|
obj.autoCapture = result.autoCapture
|
|
183
195
|
}
|
|
184
|
-
if (result.maxRecallResults !== undefined && result.maxRecallResults !==
|
|
196
|
+
if (result.maxRecallResults !== undefined && result.maxRecallResults !== DEFAULTS.maxRecallResults) {
|
|
185
197
|
obj.maxRecallResults = result.maxRecallResults
|
|
186
198
|
}
|
|
187
|
-
if (result.recallMode !== undefined && result.recallMode !==
|
|
199
|
+
if (result.recallMode !== undefined && result.recallMode !== DEFAULTS.recallMode) {
|
|
188
200
|
obj.recallMode = result.recallMode
|
|
189
201
|
}
|
|
190
|
-
if (result.graphContext !== undefined && result.graphContext !==
|
|
202
|
+
if (result.graphContext !== undefined && result.graphContext !== DEFAULTS.graphContext) {
|
|
191
203
|
obj.graphContext = result.graphContext
|
|
192
204
|
}
|
|
193
|
-
if (result.debug !== undefined && result.debug !==
|
|
205
|
+
if (result.debug !== undefined && result.debug !== DEFAULTS.debug) {
|
|
194
206
|
obj.debug = result.debug
|
|
195
207
|
}
|
|
196
208
|
|
|
197
|
-
return
|
|
209
|
+
return obj
|
|
198
210
|
}
|
|
199
211
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
212
|
+
// ── Persist to ~/.openclaw/openclaw.json ──
|
|
213
|
+
|
|
214
|
+
const OPENCLAW_CONFIG_PATH = path.join(
|
|
215
|
+
process.env.HOME ?? process.env.USERPROFILE ?? "~",
|
|
216
|
+
".openclaw",
|
|
217
|
+
"openclaw.json",
|
|
218
|
+
)
|
|
219
|
+
|
|
220
|
+
function persistConfig(configObj: Record<string, unknown>): boolean {
|
|
221
|
+
try {
|
|
222
|
+
const raw = fs.readFileSync(OPENCLAW_CONFIG_PATH, "utf-8")
|
|
223
|
+
const root = JSON.parse(raw)
|
|
224
|
+
|
|
225
|
+
if (!root.plugins) root.plugins = {}
|
|
226
|
+
if (!root.plugins.entries) root.plugins.entries = {}
|
|
227
|
+
if (!root.plugins.entries["openclaw-cortex-ai"]) {
|
|
228
|
+
root.plugins.entries["openclaw-cortex-ai"] = { enabled: true }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
root.plugins.entries["openclaw-cortex-ai"].config = configObj
|
|
232
|
+
|
|
233
|
+
fs.writeFileSync(OPENCLAW_CONFIG_PATH, JSON.stringify(root, null, 2) + "\n")
|
|
234
|
+
return true
|
|
235
|
+
} catch {
|
|
236
|
+
return false
|
|
207
237
|
}
|
|
208
|
-
return lines
|
|
209
238
|
}
|
|
210
239
|
|
|
211
240
|
// ── Wizards ──
|
|
212
241
|
|
|
213
|
-
async function runBasicWizard(cfg
|
|
242
|
+
async function runBasicWizard(cfg?: CortexPluginConfig): Promise<void> {
|
|
214
243
|
const rl = createRl()
|
|
215
244
|
|
|
216
245
|
try {
|
|
@@ -232,14 +261,15 @@ async function runBasicWizard(cfg: CortexPluginConfig): Promise<void> {
|
|
|
232
261
|
printSection("Customisation")
|
|
233
262
|
|
|
234
263
|
const subTenantId = await promptText(rl, "Sub-Tenant ID", {
|
|
235
|
-
default: cfg.subTenantId,
|
|
264
|
+
default: cfg?.subTenantId ?? DEFAULTS.subTenantId,
|
|
236
265
|
})
|
|
237
266
|
|
|
238
267
|
const ignoreTerm = await promptText(rl, "Ignore Term", {
|
|
239
|
-
default: cfg.ignoreTerm,
|
|
268
|
+
default: cfg?.ignoreTerm ?? DEFAULTS.ignoreTerm,
|
|
240
269
|
})
|
|
241
270
|
|
|
242
271
|
const result: WizardResult = { apiKey, tenantId, subTenantId, ignoreTerm }
|
|
272
|
+
const configObj = buildConfigObj(result)
|
|
243
273
|
|
|
244
274
|
// ── Summary ──
|
|
245
275
|
|
|
@@ -252,35 +282,35 @@ async function runBasicWizard(cfg: CortexPluginConfig): Promise<void> {
|
|
|
252
282
|
printSummaryRow("Ignore Term", ignoreTerm)
|
|
253
283
|
console.log(` ${c.dim}└${"─".repeat(50)}${c.reset}`)
|
|
254
284
|
|
|
255
|
-
// ──
|
|
285
|
+
// ── Persist config ──
|
|
256
286
|
|
|
257
|
-
const
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
287
|
+
const saved = await promptBool(rl, `Write config to ${OPENCLAW_CONFIG_PATH}?`, true)
|
|
288
|
+
|
|
289
|
+
if (saved && persistConfig(configObj)) {
|
|
290
|
+
printSuccess("Config saved! Restart the gateway (`openclaw gateway restart`) to apply.")
|
|
291
|
+
} else if (saved) {
|
|
292
|
+
console.log(` ${c.red}Failed to write config. Add manually:${c.reset}`)
|
|
261
293
|
console.log()
|
|
262
|
-
for (const line of
|
|
263
|
-
console.log(` ${c.
|
|
294
|
+
for (const line of JSON.stringify(configObj, null, 2).split("\n")) {
|
|
295
|
+
console.log(` ${c.cyan}${line}${c.reset}`)
|
|
264
296
|
}
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const json = buildConfigJson(result)
|
|
268
|
-
if (json !== "{}") {
|
|
297
|
+
} else {
|
|
269
298
|
console.log()
|
|
270
|
-
console.log(` ${c.yellow}${c.bold}
|
|
299
|
+
console.log(` ${c.yellow}${c.bold}Add to openclaw.json plugins.entries.openclaw-cortex-ai.config:${c.reset}`)
|
|
271
300
|
console.log()
|
|
272
|
-
for (const line of
|
|
301
|
+
for (const line of JSON.stringify(configObj, null, 2).split("\n")) {
|
|
273
302
|
console.log(` ${c.cyan}${line}${c.reset}`)
|
|
274
303
|
}
|
|
275
304
|
}
|
|
276
305
|
|
|
277
|
-
|
|
306
|
+
console.log()
|
|
307
|
+
console.log(` ${c.dim}Run \`cortex onboard --advanced\` to fine-tune all options.${c.reset}`)
|
|
278
308
|
} finally {
|
|
279
309
|
rl.close()
|
|
280
310
|
}
|
|
281
311
|
}
|
|
282
312
|
|
|
283
|
-
async function runAdvancedWizard(cfg
|
|
313
|
+
async function runAdvancedWizard(cfg?: CortexPluginConfig): Promise<void> {
|
|
284
314
|
const rl = createRl()
|
|
285
315
|
|
|
286
316
|
try {
|
|
@@ -300,30 +330,30 @@ async function runAdvancedWizard(cfg: CortexPluginConfig): Promise<void> {
|
|
|
300
330
|
})
|
|
301
331
|
|
|
302
332
|
const subTenantId = await promptText(rl, "Sub-Tenant ID", {
|
|
303
|
-
default: cfg.subTenantId,
|
|
333
|
+
default: cfg?.subTenantId ?? DEFAULTS.subTenantId,
|
|
304
334
|
})
|
|
305
335
|
|
|
306
336
|
printSection("Behaviour")
|
|
307
337
|
|
|
308
|
-
const autoRecall = await promptBool(rl, "Enable Auto-Recall?", cfg.autoRecall)
|
|
309
|
-
const autoCapture = await promptBool(rl, "Enable Auto-Capture?", cfg.autoCapture)
|
|
338
|
+
const autoRecall = await promptBool(rl, "Enable Auto-Recall?", cfg?.autoRecall ?? DEFAULTS.autoRecall)
|
|
339
|
+
const autoCapture = await promptBool(rl, "Enable Auto-Capture?", cfg?.autoCapture ?? DEFAULTS.autoCapture)
|
|
310
340
|
const ignoreTerm = await promptText(rl, "Ignore Term", {
|
|
311
|
-
default: cfg.ignoreTerm,
|
|
341
|
+
default: cfg?.ignoreTerm ?? DEFAULTS.ignoreTerm,
|
|
312
342
|
})
|
|
313
343
|
|
|
314
344
|
printSection("Recall Settings")
|
|
315
345
|
|
|
316
346
|
const maxRecallResults = await promptNumber(
|
|
317
|
-
rl, "Max Recall Results", cfg.maxRecallResults, 1, 50,
|
|
347
|
+
rl, "Max Recall Results", cfg?.maxRecallResults ?? DEFAULTS.maxRecallResults, 1, 50,
|
|
318
348
|
)
|
|
319
349
|
const recallMode = await promptChoice(
|
|
320
|
-
rl, "Recall Mode", ["fast", "thinking"], cfg.recallMode,
|
|
350
|
+
rl, "Recall Mode", ["fast", "thinking"], cfg?.recallMode ?? DEFAULTS.recallMode,
|
|
321
351
|
) as "fast" | "thinking"
|
|
322
|
-
const graphContext = await promptBool(rl, "Enable Graph Context?", cfg.graphContext)
|
|
352
|
+
const graphContext = await promptBool(rl, "Enable Graph Context?", cfg?.graphContext ?? DEFAULTS.graphContext)
|
|
323
353
|
|
|
324
354
|
printSection("Debug")
|
|
325
355
|
|
|
326
|
-
const debug = await promptBool(rl, "Enable Debug Logging?", cfg.debug)
|
|
356
|
+
const debug = await promptBool(rl, "Enable Debug Logging?", cfg?.debug ?? DEFAULTS.debug)
|
|
327
357
|
|
|
328
358
|
const result: WizardResult = {
|
|
329
359
|
apiKey,
|
|
@@ -355,29 +385,27 @@ async function runAdvancedWizard(cfg: CortexPluginConfig): Promise<void> {
|
|
|
355
385
|
printSummaryRow("Debug", String(debug))
|
|
356
386
|
console.log(` ${c.dim}└${"─".repeat(50)}${c.reset}`)
|
|
357
387
|
|
|
358
|
-
// ──
|
|
388
|
+
// ── Persist config ──
|
|
359
389
|
|
|
360
|
-
const
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
390
|
+
const configObj = buildConfigObj(result)
|
|
391
|
+
const saved = await promptBool(rl, `Write config to ${OPENCLAW_CONFIG_PATH}?`, true)
|
|
392
|
+
|
|
393
|
+
if (saved && persistConfig(configObj)) {
|
|
394
|
+
printSuccess("Config saved! Restart the gateway (`openclaw gateway restart`) to apply.")
|
|
395
|
+
} else if (saved) {
|
|
396
|
+
console.log(` ${c.red}Failed to write config. Add manually:${c.reset}`)
|
|
364
397
|
console.log()
|
|
365
|
-
for (const line of
|
|
366
|
-
console.log(` ${c.
|
|
398
|
+
for (const line of JSON.stringify(configObj, null, 2).split("\n")) {
|
|
399
|
+
console.log(` ${c.cyan}${line}${c.reset}`)
|
|
367
400
|
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
const json = buildConfigJson(result)
|
|
371
|
-
if (json !== "{}") {
|
|
401
|
+
} else {
|
|
372
402
|
console.log()
|
|
373
|
-
console.log(` ${c.yellow}${c.bold}
|
|
403
|
+
console.log(` ${c.yellow}${c.bold}Add to openclaw.json plugins.entries.openclaw-cortex-ai.config:${c.reset}`)
|
|
374
404
|
console.log()
|
|
375
|
-
for (const line of
|
|
405
|
+
for (const line of JSON.stringify(configObj, null, 2).split("\n")) {
|
|
376
406
|
console.log(` ${c.cyan}${line}${c.reset}`)
|
|
377
407
|
}
|
|
378
408
|
}
|
|
379
|
-
|
|
380
|
-
printSuccess("Onboarding complete! All options configured.")
|
|
381
409
|
} finally {
|
|
382
410
|
rl.close()
|
|
383
411
|
}
|
|
@@ -386,7 +414,7 @@ async function runAdvancedWizard(cfg: CortexPluginConfig): Promise<void> {
|
|
|
386
414
|
// ── Registration (CLI + Slash) ──
|
|
387
415
|
|
|
388
416
|
export function registerOnboardingCli(
|
|
389
|
-
cfg
|
|
417
|
+
cfg?: CortexPluginConfig,
|
|
390
418
|
): (root: any) => void {
|
|
391
419
|
return (root: any) => {
|
|
392
420
|
root
|
package/config.ts
CHANGED
|
@@ -97,6 +97,32 @@ export function parseConfig(raw: unknown): CortexPluginConfig {
|
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
100
|
+
export function tryParseConfig(raw: unknown): CortexPluginConfig | null {
|
|
101
|
+
try {
|
|
102
|
+
return parseConfig(raw)
|
|
103
|
+
} catch {
|
|
104
|
+
return null
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Permissive schema parse — validates key names but does NOT require credentials.
|
|
110
|
+
* This lets the plugin load so the onboarding wizard can run.
|
|
111
|
+
*/
|
|
112
|
+
function parseConfigSoft(raw: unknown): Record<string, unknown> {
|
|
113
|
+
const cfg =
|
|
114
|
+
raw && typeof raw === "object" && !Array.isArray(raw)
|
|
115
|
+
? (raw as Record<string, unknown>)
|
|
116
|
+
: {}
|
|
117
|
+
|
|
118
|
+
const unknown = Object.keys(cfg).filter((k) => !KNOWN_KEYS.has(k))
|
|
119
|
+
if (unknown.length > 0) {
|
|
120
|
+
throw new Error(`cortex-ai: unrecognized config keys: ${unknown.join(", ")}`)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return cfg
|
|
124
|
+
}
|
|
125
|
+
|
|
100
126
|
export const cortexConfigSchema = {
|
|
101
|
-
parse:
|
|
127
|
+
parse: parseConfigSoft,
|
|
102
128
|
}
|
package/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
|
|
2
2
|
import { CortexClient } from "./client.ts"
|
|
3
|
-
import {
|
|
4
|
-
import { registerOnboardingCli, registerOnboardingSlashCommands } from "./commands/onboarding.ts"
|
|
3
|
+
import type { CortexPluginConfig } from "./config.ts"
|
|
4
|
+
import { registerOnboardingCli as createOnboardingCliRegistrar, registerOnboardingSlashCommands } from "./commands/onboarding.ts"
|
|
5
5
|
import { registerSlashCommands } from "./commands/slash.ts"
|
|
6
|
-
import { cortexConfigSchema,
|
|
6
|
+
import { cortexConfigSchema, tryParseConfig } from "./config.ts"
|
|
7
7
|
import { createIngestionHook } from "./hooks/capture.ts"
|
|
8
8
|
import { createRecallHook } from "./hooks/recall.ts"
|
|
9
9
|
import { log } from "./log.ts"
|
|
@@ -13,6 +13,9 @@ import { registerListTool } from "./tools/list.ts"
|
|
|
13
13
|
import { registerSearchTool } from "./tools/search.ts"
|
|
14
14
|
import { registerStoreTool } from "./tools/store.ts"
|
|
15
15
|
|
|
16
|
+
const NOT_CONFIGURED_MSG =
|
|
17
|
+
"[cortex-ai] Not configured. Run `openclaw cortex onboard` to set up credentials."
|
|
18
|
+
|
|
16
19
|
export default {
|
|
17
20
|
id: "openclaw-cortex-ai",
|
|
18
21
|
name: "Cortex AI",
|
|
@@ -22,8 +25,33 @@ export default {
|
|
|
22
25
|
configSchema: cortexConfigSchema,
|
|
23
26
|
|
|
24
27
|
register(api: OpenClawPluginApi) {
|
|
25
|
-
const cfg =
|
|
28
|
+
const cfg = tryParseConfig(api.pluginConfig)
|
|
29
|
+
const cliClient = cfg ? new CortexClient(cfg.apiKey, cfg.tenantId, cfg.subTenantId) : null
|
|
30
|
+
|
|
31
|
+
// Always register ALL CLI commands so they appear in help text.
|
|
32
|
+
// Non-onboard commands guard on credentials at runtime.
|
|
33
|
+
api.registerCli(
|
|
34
|
+
({ program }: { program: any }) => {
|
|
35
|
+
const root = program
|
|
36
|
+
.command("cortex")
|
|
37
|
+
.description("Cortex AI memory commands")
|
|
38
|
+
|
|
39
|
+
createOnboardingCliRegistrar(cfg ?? undefined)(root)
|
|
40
|
+
registerCortexCliCommands(root, cliClient, cfg)
|
|
41
|
+
},
|
|
42
|
+
{ commands: ["cortex"] },
|
|
43
|
+
)
|
|
26
44
|
|
|
45
|
+
if (!cfg) {
|
|
46
|
+
api.registerService({
|
|
47
|
+
id: "openclaw-cortex-ai",
|
|
48
|
+
start: () => console.log(NOT_CONFIGURED_MSG),
|
|
49
|
+
stop: () => {},
|
|
50
|
+
})
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Full plugin registration — credentials present
|
|
27
55
|
log.init(api.logger, cfg.debug)
|
|
28
56
|
|
|
29
57
|
const client = new CortexClient(cfg.apiKey, cfg.tenantId, cfg.subTenantId)
|
|
@@ -67,7 +95,6 @@ export default {
|
|
|
67
95
|
|
|
68
96
|
registerSlashCommands(api, client, cfg, getSessionId)
|
|
69
97
|
registerOnboardingSlashCommands(api, client, cfg)
|
|
70
|
-
registerCliCommands(api, client, cfg, registerOnboardingCli(cfg))
|
|
71
98
|
|
|
72
99
|
api.registerService({
|
|
73
100
|
id: "openclaw-cortex-ai",
|
|
@@ -76,3 +103,110 @@ export default {
|
|
|
76
103
|
})
|
|
77
104
|
},
|
|
78
105
|
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Register all `cortex *` CLI subcommands.
|
|
109
|
+
* Commands other than `onboard` guard on valid credentials at runtime.
|
|
110
|
+
*/
|
|
111
|
+
function registerCortexCliCommands(
|
|
112
|
+
root: any,
|
|
113
|
+
client: CortexClient | null,
|
|
114
|
+
cfg: CortexPluginConfig | null,
|
|
115
|
+
): void {
|
|
116
|
+
const requireCreds = (): { client: CortexClient; cfg: CortexPluginConfig } | null => {
|
|
117
|
+
if (client && cfg) return { client, cfg }
|
|
118
|
+
console.error(NOT_CONFIGURED_MSG)
|
|
119
|
+
return null
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
root
|
|
123
|
+
.command("search")
|
|
124
|
+
.argument("<query>", "Search query")
|
|
125
|
+
.option("--limit <n>", "Max results", "10")
|
|
126
|
+
.action(async (query: string, opts: { limit: string }) => {
|
|
127
|
+
const ctx = requireCreds()
|
|
128
|
+
if (!ctx) return
|
|
129
|
+
|
|
130
|
+
const limit = Number.parseInt(opts.limit, 10) || 10
|
|
131
|
+
const res = await ctx.client.recall(query, {
|
|
132
|
+
maxResults: limit,
|
|
133
|
+
mode: ctx.cfg.recallMode,
|
|
134
|
+
graphContext: ctx.cfg.graphContext,
|
|
135
|
+
})
|
|
136
|
+
|
|
137
|
+
if (!res.chunks || res.chunks.length === 0) {
|
|
138
|
+
console.log("No memories found.")
|
|
139
|
+
return
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
for (const chunk of res.chunks) {
|
|
143
|
+
const score = chunk.relevancy_score != null
|
|
144
|
+
? ` (${(chunk.relevancy_score * 100).toFixed(0)}%)`
|
|
145
|
+
: ""
|
|
146
|
+
const title = chunk.source_title ? `[${chunk.source_title}] ` : ""
|
|
147
|
+
console.log(`- ${title}${chunk.chunk_content.slice(0, 200)}${score}`)
|
|
148
|
+
}
|
|
149
|
+
})
|
|
150
|
+
|
|
151
|
+
root
|
|
152
|
+
.command("list")
|
|
153
|
+
.description("List all user memories")
|
|
154
|
+
.action(async () => {
|
|
155
|
+
const ctx = requireCreds()
|
|
156
|
+
if (!ctx) return
|
|
157
|
+
|
|
158
|
+
const res = await ctx.client.listMemories()
|
|
159
|
+
const memories = res.user_memories ?? []
|
|
160
|
+
if (memories.length === 0) {
|
|
161
|
+
console.log("No memories stored.")
|
|
162
|
+
return
|
|
163
|
+
}
|
|
164
|
+
for (const m of memories) {
|
|
165
|
+
console.log(`[${m.memory_id}] ${m.memory_content.slice(0, 150)}`)
|
|
166
|
+
}
|
|
167
|
+
console.log(`\nTotal: ${memories.length}`)
|
|
168
|
+
})
|
|
169
|
+
|
|
170
|
+
root
|
|
171
|
+
.command("delete")
|
|
172
|
+
.argument("<memory_id>", "Memory ID to delete")
|
|
173
|
+
.action(async (memoryId: string) => {
|
|
174
|
+
const ctx = requireCreds()
|
|
175
|
+
if (!ctx) return
|
|
176
|
+
|
|
177
|
+
const res = await ctx.client.deleteMemory(memoryId)
|
|
178
|
+
console.log(res.user_memory_deleted ? `Deleted: ${memoryId}` : `Not found: ${memoryId}`)
|
|
179
|
+
})
|
|
180
|
+
|
|
181
|
+
root
|
|
182
|
+
.command("get")
|
|
183
|
+
.argument("<source_id>", "Source ID to fetch")
|
|
184
|
+
.action(async (sourceId: string) => {
|
|
185
|
+
const ctx = requireCreds()
|
|
186
|
+
if (!ctx) return
|
|
187
|
+
|
|
188
|
+
const res = await ctx.client.fetchContent(sourceId)
|
|
189
|
+
if (!res.success || res.error) {
|
|
190
|
+
console.error(`Error: ${res.error ?? "unknown"}`)
|
|
191
|
+
return
|
|
192
|
+
}
|
|
193
|
+
console.log(res.content ?? res.content_base64 ?? "(no text content)")
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
root
|
|
197
|
+
.command("status")
|
|
198
|
+
.description("Show plugin configuration")
|
|
199
|
+
.action(() => {
|
|
200
|
+
const ctx = requireCreds()
|
|
201
|
+
if (!ctx) return
|
|
202
|
+
|
|
203
|
+
console.log(`Tenant: ${ctx.client.getTenantId()}`)
|
|
204
|
+
console.log(`Sub-Tenant: ${ctx.client.getSubTenantId()}`)
|
|
205
|
+
console.log(`Auto-Recall: ${ctx.cfg.autoRecall}`)
|
|
206
|
+
console.log(`Auto-Capture: ${ctx.cfg.autoCapture}`)
|
|
207
|
+
console.log(`Recall Mode: ${ctx.cfg.recallMode}`)
|
|
208
|
+
console.log(`Graph: ${ctx.cfg.graphContext}`)
|
|
209
|
+
console.log(`Max Results: ${ctx.cfg.maxRecallResults}`)
|
|
210
|
+
console.log(`Ignore Term: ${ctx.cfg.ignoreTerm}`)
|
|
211
|
+
})
|
|
212
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usecortex_ai/openclaw-cortex-ai",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenClaw plugin for Cortex AI — the State-of-the-art agentic memory system with auto-capture, recall, and knowledge graph context for open-claw",
|
|
6
6
|
"license": "MIT",
|