@basicmemory/openclaw-basic-memory 0.2.3 → 0.23.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/README.md +49 -19
- package/bm-client.ts +55 -21
- package/commands/cli.ts +1 -2
- package/commands/skills.ts +71 -10
- package/commands/slash.ts +4 -2
- package/config.ts +0 -16
- package/context-engine/basic-memory-context-engine.ts +22 -90
- package/dist/bm-client.d.ts +179 -0
- package/dist/bm-client.js +582 -0
- package/dist/commands/cli.d.ts +4 -0
- package/dist/commands/cli.js +116 -0
- package/dist/commands/skills.d.ts +2 -0
- package/dist/commands/skills.js +86 -0
- package/dist/commands/slash.d.ts +3 -0
- package/dist/commands/slash.js +92 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +99 -0
- package/dist/context-engine/basic-memory-context-engine.d.ts +34 -0
- package/dist/context-engine/basic-memory-context-engine.js +176 -0
- package/dist/hooks/capture.d.ts +24 -0
- package/dist/hooks/capture.js +88 -0
- package/dist/hooks/recall.d.ts +24 -0
- package/dist/hooks/recall.js +56 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +135 -0
- package/dist/logger.d.ts +13 -0
- package/dist/logger.js +34 -0
- package/dist/schema/conversation-schema.d.ts +5 -0
- package/dist/schema/conversation-schema.js +33 -0
- package/dist/schema/task-schema.d.ts +5 -0
- package/dist/schema/task-schema.js +34 -0
- package/dist/tools/build-context.d.ts +3 -0
- package/dist/tools/build-context.js +100 -0
- package/dist/tools/delete-note.d.ts +3 -0
- package/dist/tools/delete-note.js +52 -0
- package/dist/tools/edit-note.d.ts +3 -0
- package/dist/tools/edit-note.js +81 -0
- package/dist/tools/list-memory-projects.d.ts +3 -0
- package/dist/tools/list-memory-projects.js +86 -0
- package/dist/tools/list-workspaces.d.ts +3 -0
- package/dist/tools/list-workspaces.js +64 -0
- package/dist/tools/memory-provider.d.ts +15 -0
- package/dist/tools/memory-provider.js +274 -0
- package/dist/tools/move-note.d.ts +3 -0
- package/dist/tools/move-note.js +56 -0
- package/dist/tools/read-note.d.ts +3 -0
- package/dist/tools/read-note.js +57 -0
- package/dist/tools/schema-diff.d.ts +3 -0
- package/dist/tools/schema-diff.js +81 -0
- package/dist/tools/schema-infer.d.ts +3 -0
- package/dist/tools/schema-infer.js +66 -0
- package/dist/tools/schema-validate.d.ts +3 -0
- package/dist/tools/schema-validate.js +73 -0
- package/dist/tools/search-notes.d.ts +3 -0
- package/dist/tools/search-notes.js +97 -0
- package/dist/tools/write-note.d.ts +3 -0
- package/dist/tools/write-note.js +80 -0
- package/index.ts +27 -17
- package/openclaw.plugin.json +27 -20
- package/package.json +27 -8
- package/scripts/fetch-skills.ts +62 -67
- package/scripts/setup-bm.sh +27 -10
- package/skills/manifest.json +25 -0
- package/skills/memory-capture/SKILL.md +275 -0
- package/skills/memory-ci-capture/SKILL.md +56 -0
- package/skills/memory-continue/SKILL.md +148 -0
- package/skills/memory-curate/SKILL.md +243 -0
- package/skills/memory-literary-analysis/SKILL.md +15 -12
- package/skills/memory-notes/SKILL.md +22 -6
- package/skills/memory-onboarding/SKILL.md +142 -0
- package/skills/memory-onboarding/evals/evals.json +29 -0
- package/skills/memory-onboarding/references/assistant-setup.md +64 -0
- package/skills/memory-onboarding/references/conventions.md +118 -0
- package/skills/memory-onboarding/references/domain-playbooks.md +159 -0
- package/skills/memory-onboarding/references/schema-guide.md +136 -0
- package/skills/memory-schema/SKILL.md +7 -5
- package/skills/memory-tasks/SKILL.md +1 -1
- package/tools/build-context.ts +1 -1
- package/tools/delete-note.ts +1 -1
- package/tools/edit-note.ts +1 -1
- package/tools/list-memory-projects.ts +3 -2
- package/tools/list-workspaces.ts +1 -1
- package/tools/memory-provider.ts +1 -1
- package/tools/move-note.ts +1 -1
- package/tools/read-note.ts +1 -1
- package/tools/schema-diff.ts +1 -1
- package/tools/schema-infer.ts +1 -1
- package/tools/schema-validate.ts +1 -1
- package/tools/search-notes.ts +1 -1
- package/tools/write-note.ts +1 -1
- package/context-engine/basic-memory-context-engine.test.ts +0 -398
|
@@ -1,25 +1,33 @@
|
|
|
1
|
-
import { createRequire } from "node:module"
|
|
2
|
-
import { dirname, resolve } from "node:path"
|
|
3
|
-
import { pathToFileURL } from "node:url"
|
|
4
|
-
import type { AgentMessage } from "@mariozechner/pi-agent-core"
|
|
5
1
|
import type {
|
|
6
2
|
AssembleResult,
|
|
7
3
|
BootstrapResult,
|
|
8
4
|
CompactResult,
|
|
9
5
|
ContextEngine,
|
|
6
|
+
SubagentSpawnPreparation,
|
|
10
7
|
} from "openclaw/plugin-sdk"
|
|
8
|
+
import { delegateCompactionToRuntime } from "openclaw/plugin-sdk/core"
|
|
11
9
|
import type { BmClient } from "../bm-client.ts"
|
|
12
10
|
import type { BasicMemoryConfig } from "../config.ts"
|
|
13
11
|
import { selectCaptureTurn } from "../hooks/capture.ts"
|
|
14
12
|
import { loadRecallState } from "../hooks/recall.ts"
|
|
15
13
|
import { log } from "../logger.ts"
|
|
16
14
|
|
|
17
|
-
const require = createRequire(import.meta.url)
|
|
18
15
|
export const MAX_ASSEMBLE_RECALL_CHARS = 1200
|
|
19
16
|
const TRUNCATED_RECALL_SUFFIX = "\n\n[Basic Memory recall truncated]"
|
|
20
17
|
const SUBAGENT_HANDOFF_FOLDER = "agent/subagents"
|
|
21
18
|
const MAX_SUBAGENT_RECALL_CHARS = 800
|
|
22
19
|
|
|
20
|
+
type BootstrapParams = Parameters<NonNullable<ContextEngine["bootstrap"]>>[0]
|
|
21
|
+
type AssembleParams = Parameters<ContextEngine["assemble"]>[0]
|
|
22
|
+
type AfterTurnParams = Parameters<NonNullable<ContextEngine["afterTurn"]>>[0]
|
|
23
|
+
type CompactParams = Parameters<ContextEngine["compact"]>[0]
|
|
24
|
+
type PrepareSubagentSpawnParams = Parameters<
|
|
25
|
+
NonNullable<ContextEngine["prepareSubagentSpawn"]>
|
|
26
|
+
>[0]
|
|
27
|
+
type OnSubagentEndedParams = Parameters<
|
|
28
|
+
NonNullable<ContextEngine["onSubagentEnded"]>
|
|
29
|
+
>[0]
|
|
30
|
+
|
|
23
31
|
interface SessionMemoryState {
|
|
24
32
|
recallContext: string
|
|
25
33
|
}
|
|
@@ -104,36 +112,6 @@ function buildSubagentCompletionUpdate(params: {
|
|
|
104
112
|
].join("\n")
|
|
105
113
|
}
|
|
106
114
|
|
|
107
|
-
type LegacyContextEngineModule = {
|
|
108
|
-
LegacyContextEngine: new () => {
|
|
109
|
-
compact(params: {
|
|
110
|
-
sessionId: string
|
|
111
|
-
sessionFile: string
|
|
112
|
-
tokenBudget?: number
|
|
113
|
-
force?: boolean
|
|
114
|
-
currentTokenCount?: number
|
|
115
|
-
compactionTarget?: "budget" | "threshold"
|
|
116
|
-
customInstructions?: string
|
|
117
|
-
runtimeContext?: Record<string, unknown>
|
|
118
|
-
}): Promise<CompactResult>
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
async function loadLegacyContextEngine(): Promise<
|
|
123
|
-
LegacyContextEngineModule["LegacyContextEngine"]
|
|
124
|
-
> {
|
|
125
|
-
const pluginSdkPath = require.resolve("openclaw/plugin-sdk")
|
|
126
|
-
const legacyPath = resolve(
|
|
127
|
-
dirname(pluginSdkPath),
|
|
128
|
-
"context-engine",
|
|
129
|
-
"legacy.js",
|
|
130
|
-
)
|
|
131
|
-
const module = (await import(
|
|
132
|
-
pathToFileURL(legacyPath).href
|
|
133
|
-
)) as LegacyContextEngineModule
|
|
134
|
-
return module.LegacyContextEngine
|
|
135
|
-
}
|
|
136
|
-
|
|
137
115
|
export class BasicMemoryContextEngine implements ContextEngine {
|
|
138
116
|
readonly info = {
|
|
139
117
|
id: "openclaw-basic-memory",
|
|
@@ -144,19 +122,13 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
144
122
|
|
|
145
123
|
private readonly sessionState = new Map<string, SessionMemoryState>()
|
|
146
124
|
private readonly subagentState = new Map<string, SubagentHandoffState>()
|
|
147
|
-
private legacyContextEnginePromise: Promise<
|
|
148
|
-
InstanceType<LegacyContextEngineModule["LegacyContextEngine"]>
|
|
149
|
-
> | null = null
|
|
150
125
|
|
|
151
126
|
constructor(
|
|
152
127
|
private readonly client: BmClient,
|
|
153
128
|
private readonly cfg: BasicMemoryConfig,
|
|
154
129
|
) {}
|
|
155
130
|
|
|
156
|
-
async bootstrap(params: {
|
|
157
|
-
sessionId: string
|
|
158
|
-
sessionFile: string
|
|
159
|
-
}): Promise<BootstrapResult> {
|
|
131
|
+
async bootstrap(params: BootstrapParams): Promise<BootstrapResult> {
|
|
160
132
|
if (!this.cfg.autoRecall) {
|
|
161
133
|
this.sessionState.delete(params.sessionId)
|
|
162
134
|
return { bootstrapped: false, reason: "autoRecall disabled" }
|
|
@@ -189,11 +161,7 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
189
161
|
return { ingested: false }
|
|
190
162
|
}
|
|
191
163
|
|
|
192
|
-
async assemble(params: {
|
|
193
|
-
sessionId: string
|
|
194
|
-
messages: AgentMessage[]
|
|
195
|
-
tokenBudget?: number
|
|
196
|
-
}): Promise<AssembleResult> {
|
|
164
|
+
async assemble(params: AssembleParams): Promise<AssembleResult> {
|
|
197
165
|
const state = this.sessionState.get(params.sessionId)
|
|
198
166
|
|
|
199
167
|
return {
|
|
@@ -203,16 +171,7 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
203
171
|
}
|
|
204
172
|
}
|
|
205
173
|
|
|
206
|
-
async afterTurn(params: {
|
|
207
|
-
sessionId: string
|
|
208
|
-
sessionFile: string
|
|
209
|
-
messages: AgentMessage[]
|
|
210
|
-
prePromptMessageCount: number
|
|
211
|
-
autoCompactionSummary?: string
|
|
212
|
-
isHeartbeat?: boolean
|
|
213
|
-
tokenBudget?: number
|
|
214
|
-
runtimeContext?: Record<string, unknown>
|
|
215
|
-
}): Promise<void> {
|
|
174
|
+
async afterTurn(params: AfterTurnParams): Promise<void> {
|
|
216
175
|
if (!this.cfg.autoCapture) return
|
|
217
176
|
|
|
218
177
|
const newMessages = params.messages.slice(params.prePromptMessageCount)
|
|
@@ -233,25 +192,13 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
233
192
|
}
|
|
234
193
|
}
|
|
235
194
|
|
|
236
|
-
async compact(params: {
|
|
237
|
-
|
|
238
|
-
sessionFile: string
|
|
239
|
-
tokenBudget?: number
|
|
240
|
-
force?: boolean
|
|
241
|
-
currentTokenCount?: number
|
|
242
|
-
compactionTarget?: "budget" | "threshold"
|
|
243
|
-
customInstructions?: string
|
|
244
|
-
runtimeContext?: Record<string, unknown>
|
|
245
|
-
}): Promise<CompactResult> {
|
|
246
|
-
const legacy = await this.getLegacyContextEngine()
|
|
247
|
-
return legacy.compact(params)
|
|
195
|
+
async compact(params: CompactParams): Promise<CompactResult> {
|
|
196
|
+
return delegateCompactionToRuntime(params)
|
|
248
197
|
}
|
|
249
198
|
|
|
250
|
-
async prepareSubagentSpawn(
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
ttlMs?: number
|
|
254
|
-
}): Promise<{ rollback: () => Promise<void> } | undefined> {
|
|
199
|
+
async prepareSubagentSpawn(
|
|
200
|
+
params: PrepareSubagentSpawnParams,
|
|
201
|
+
): Promise<SubagentSpawnPreparation | undefined> {
|
|
255
202
|
const parentState = this.sessionState.get(params.parentSessionKey)
|
|
256
203
|
const noteTitle = buildSubagentNoteTitle(params.childSessionKey)
|
|
257
204
|
|
|
@@ -291,10 +238,7 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
291
238
|
}
|
|
292
239
|
}
|
|
293
240
|
|
|
294
|
-
async onSubagentEnded(params: {
|
|
295
|
-
childSessionKey: string
|
|
296
|
-
reason: "deleted" | "completed" | "swept" | "released"
|
|
297
|
-
}): Promise<void> {
|
|
241
|
+
async onSubagentEnded(params: OnSubagentEndedParams): Promise<void> {
|
|
298
242
|
const handoff = this.subagentState.get(params.childSessionKey)
|
|
299
243
|
if (!handoff) return
|
|
300
244
|
|
|
@@ -315,16 +259,4 @@ export class BasicMemoryContextEngine implements ContextEngine {
|
|
|
315
259
|
this.sessionState.clear()
|
|
316
260
|
this.subagentState.clear()
|
|
317
261
|
}
|
|
318
|
-
|
|
319
|
-
private async getLegacyContextEngine(): Promise<
|
|
320
|
-
InstanceType<LegacyContextEngineModule["LegacyContextEngine"]>
|
|
321
|
-
> {
|
|
322
|
-
if (!this.legacyContextEnginePromise) {
|
|
323
|
-
this.legacyContextEnginePromise = loadLegacyContextEngine().then(
|
|
324
|
-
(LegacyContextEngine) => new LegacyContextEngine(),
|
|
325
|
-
)
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
return this.legacyContextEnginePromise
|
|
329
|
-
}
|
|
330
262
|
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
export declare class NoteAlreadyExistsError extends Error {
|
|
2
|
+
readonly permalink: string;
|
|
3
|
+
constructor(title: string, permalink: string);
|
|
4
|
+
}
|
|
5
|
+
export interface SearchResult {
|
|
6
|
+
title: string;
|
|
7
|
+
permalink: string;
|
|
8
|
+
content: string;
|
|
9
|
+
score?: number;
|
|
10
|
+
file_path: string;
|
|
11
|
+
}
|
|
12
|
+
export interface NoteResult {
|
|
13
|
+
title: string;
|
|
14
|
+
permalink: string;
|
|
15
|
+
content: string;
|
|
16
|
+
file_path: string;
|
|
17
|
+
frontmatter?: Record<string, unknown> | null;
|
|
18
|
+
checksum?: string | null;
|
|
19
|
+
action?: "created" | "updated";
|
|
20
|
+
}
|
|
21
|
+
export interface EditNoteResult {
|
|
22
|
+
title: string;
|
|
23
|
+
permalink: string;
|
|
24
|
+
file_path: string;
|
|
25
|
+
operation: "append" | "prepend" | "find_replace" | "replace_section";
|
|
26
|
+
checksum?: string | null;
|
|
27
|
+
}
|
|
28
|
+
interface ReadNoteOptions {
|
|
29
|
+
includeFrontmatter?: boolean;
|
|
30
|
+
}
|
|
31
|
+
interface EditNoteOptions {
|
|
32
|
+
find_text?: string;
|
|
33
|
+
section?: string;
|
|
34
|
+
expected_replacements?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface ContextResult {
|
|
37
|
+
results: Array<{
|
|
38
|
+
primary_result: NoteResult;
|
|
39
|
+
observations: Array<{
|
|
40
|
+
category: string;
|
|
41
|
+
content: string;
|
|
42
|
+
}>;
|
|
43
|
+
related_results: Array<{
|
|
44
|
+
type: "relation" | "entity";
|
|
45
|
+
title?: string;
|
|
46
|
+
permalink: string;
|
|
47
|
+
relation_type?: string;
|
|
48
|
+
from_entity?: string;
|
|
49
|
+
to_entity?: string;
|
|
50
|
+
}>;
|
|
51
|
+
}>;
|
|
52
|
+
}
|
|
53
|
+
export interface RecentResult {
|
|
54
|
+
title: string;
|
|
55
|
+
permalink: string;
|
|
56
|
+
file_path: string;
|
|
57
|
+
created_at: string;
|
|
58
|
+
}
|
|
59
|
+
export interface ProjectListResult {
|
|
60
|
+
name: string;
|
|
61
|
+
path: string;
|
|
62
|
+
display_name?: string | null;
|
|
63
|
+
is_private?: boolean;
|
|
64
|
+
is_default?: boolean;
|
|
65
|
+
isDefault?: boolean;
|
|
66
|
+
workspace_name?: string | null;
|
|
67
|
+
workspace_slug?: string | null;
|
|
68
|
+
workspace_type?: string | null;
|
|
69
|
+
workspace_tenant_id?: string | null;
|
|
70
|
+
}
|
|
71
|
+
export interface WorkspaceResult {
|
|
72
|
+
tenant_id: string;
|
|
73
|
+
name: string;
|
|
74
|
+
workspace_type: string;
|
|
75
|
+
role: string;
|
|
76
|
+
organization_id?: string | null;
|
|
77
|
+
has_active_subscription: boolean;
|
|
78
|
+
}
|
|
79
|
+
export interface SchemaValidationResult {
|
|
80
|
+
entity_type: string | null;
|
|
81
|
+
total_notes: number;
|
|
82
|
+
total_entities: number;
|
|
83
|
+
valid_count: number;
|
|
84
|
+
warning_count: number;
|
|
85
|
+
error_count: number;
|
|
86
|
+
results: Array<{
|
|
87
|
+
identifier: string;
|
|
88
|
+
valid: boolean;
|
|
89
|
+
warnings: string[];
|
|
90
|
+
errors: string[];
|
|
91
|
+
}>;
|
|
92
|
+
}
|
|
93
|
+
export interface SchemaInferResult {
|
|
94
|
+
entity_type: string;
|
|
95
|
+
notes_analyzed: number;
|
|
96
|
+
field_frequencies: Array<{
|
|
97
|
+
name: string;
|
|
98
|
+
percentage: number;
|
|
99
|
+
count: number;
|
|
100
|
+
total: number;
|
|
101
|
+
source: string;
|
|
102
|
+
sample_values?: string[];
|
|
103
|
+
is_array?: boolean;
|
|
104
|
+
target_type?: string | null;
|
|
105
|
+
}>;
|
|
106
|
+
suggested_schema: Record<string, unknown>;
|
|
107
|
+
suggested_required: string[];
|
|
108
|
+
suggested_optional: string[];
|
|
109
|
+
excluded: string[];
|
|
110
|
+
}
|
|
111
|
+
export interface SchemaDiffResult {
|
|
112
|
+
entity_type: string;
|
|
113
|
+
schema_found: boolean;
|
|
114
|
+
new_fields: Array<{
|
|
115
|
+
name: string;
|
|
116
|
+
source: string;
|
|
117
|
+
count: number;
|
|
118
|
+
total: number;
|
|
119
|
+
percentage: number;
|
|
120
|
+
}>;
|
|
121
|
+
dropped_fields: Array<{
|
|
122
|
+
name: string;
|
|
123
|
+
source: string;
|
|
124
|
+
declared_in?: string;
|
|
125
|
+
}>;
|
|
126
|
+
cardinality_changes: string[];
|
|
127
|
+
}
|
|
128
|
+
export declare class BmClient {
|
|
129
|
+
private bmPath;
|
|
130
|
+
private project;
|
|
131
|
+
private cwd?;
|
|
132
|
+
private env?;
|
|
133
|
+
private shouldRun;
|
|
134
|
+
private client;
|
|
135
|
+
private transport;
|
|
136
|
+
private connectPromise;
|
|
137
|
+
private retryDelaysMs;
|
|
138
|
+
constructor(bmPath: string, project: string);
|
|
139
|
+
start(options?: {
|
|
140
|
+
cwd?: string;
|
|
141
|
+
env?: Record<string, string>;
|
|
142
|
+
}): Promise<void>;
|
|
143
|
+
stop(): Promise<void>;
|
|
144
|
+
private connectWithRetries;
|
|
145
|
+
private ensureConnected;
|
|
146
|
+
private connectFresh;
|
|
147
|
+
private assertRequiredTools;
|
|
148
|
+
private disconnectCurrent;
|
|
149
|
+
private callToolRaw;
|
|
150
|
+
private callTool;
|
|
151
|
+
private routedProject;
|
|
152
|
+
ensureProject(projectPath: string): Promise<void>;
|
|
153
|
+
listWorkspaces(): Promise<WorkspaceResult[]>;
|
|
154
|
+
listProjects(workspace?: string): Promise<ProjectListResult[]>;
|
|
155
|
+
search(query?: string, limit?: number, project?: string, metadata?: {
|
|
156
|
+
filters?: Record<string, unknown>;
|
|
157
|
+
tags?: string[];
|
|
158
|
+
status?: string;
|
|
159
|
+
note_types?: string[];
|
|
160
|
+
entity_types?: string[];
|
|
161
|
+
}): Promise<SearchResult[]>;
|
|
162
|
+
readNote(identifier: string, options?: ReadNoteOptions, project?: string): Promise<NoteResult>;
|
|
163
|
+
writeNote(title: string, content: string, folder: string, project?: string, overwrite?: boolean): Promise<NoteResult>;
|
|
164
|
+
buildContext(url: string, depth?: number, project?: string): Promise<ContextResult>;
|
|
165
|
+
recentActivity(timeframe?: string, project?: string): Promise<RecentResult[]>;
|
|
166
|
+
editNote(identifier: string, operation: "append" | "prepend" | "find_replace" | "replace_section", content: string, options?: EditNoteOptions, project?: string): Promise<EditNoteResult>;
|
|
167
|
+
deleteNote(identifier: string, project?: string): Promise<{
|
|
168
|
+
title: string;
|
|
169
|
+
permalink: string;
|
|
170
|
+
file_path: string;
|
|
171
|
+
}>;
|
|
172
|
+
moveNote(identifier: string, newFolder: string, project?: string): Promise<NoteResult>;
|
|
173
|
+
schemaValidate(noteType?: string, identifier?: string, project?: string): Promise<SchemaValidationResult>;
|
|
174
|
+
schemaInfer(noteType: string, threshold?: number, project?: string): Promise<SchemaInferResult>;
|
|
175
|
+
schemaDiff(noteType: string, project?: string): Promise<SchemaDiffResult>;
|
|
176
|
+
indexConversation(userMessage: string, assistantResponse: string): Promise<void>;
|
|
177
|
+
getProject(): string;
|
|
178
|
+
}
|
|
179
|
+
export {};
|