@basicmemory/openclaw-basic-memory 0.1.4 → 0.1.5
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/bm-client.ts +19 -1
- package/package.json +1 -1
- package/tools/write-note.ts +28 -3
package/bm-client.ts
CHANGED
|
@@ -5,6 +5,15 @@ import { log } from "./logger.ts"
|
|
|
5
5
|
|
|
6
6
|
const DEFAULT_RETRY_DELAYS_MS = [500, 1000, 2000]
|
|
7
7
|
|
|
8
|
+
export class NoteAlreadyExistsError extends Error {
|
|
9
|
+
readonly permalink: string
|
|
10
|
+
constructor(title: string, permalink: string) {
|
|
11
|
+
super(`Note already exists: "${title}" (${permalink})`)
|
|
12
|
+
this.name = "NoteAlreadyExistsError"
|
|
13
|
+
this.permalink = permalink
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
8
17
|
const REQUIRED_TOOLS = [
|
|
9
18
|
"search_notes",
|
|
10
19
|
"read_note",
|
|
@@ -569,6 +578,7 @@ export class BmClient {
|
|
|
569
578
|
content: string,
|
|
570
579
|
folder: string,
|
|
571
580
|
project?: string,
|
|
581
|
+
overwrite?: boolean,
|
|
572
582
|
): Promise<NoteResult> {
|
|
573
583
|
const args: Record<string, unknown> = {
|
|
574
584
|
title,
|
|
@@ -577,6 +587,7 @@ export class BmClient {
|
|
|
577
587
|
output_format: "json",
|
|
578
588
|
}
|
|
579
589
|
if (project) args.project = project
|
|
590
|
+
if (overwrite !== undefined) args.overwrite = overwrite
|
|
580
591
|
|
|
581
592
|
const payload = await this.callTool("write_note", args)
|
|
582
593
|
|
|
@@ -584,6 +595,13 @@ export class BmClient {
|
|
|
584
595
|
throw new Error("invalid write_note response")
|
|
585
596
|
}
|
|
586
597
|
|
|
598
|
+
if (payload.error === "NOTE_ALREADY_EXISTS") {
|
|
599
|
+
throw new NoteAlreadyExistsError(
|
|
600
|
+
asString(payload.title) ?? title,
|
|
601
|
+
asString(payload.permalink) ?? "",
|
|
602
|
+
)
|
|
603
|
+
}
|
|
604
|
+
|
|
587
605
|
const resultTitle = asString(payload.title)
|
|
588
606
|
const permalink = asString(payload.permalink)
|
|
589
607
|
const filePath = asString(payload.file_path)
|
|
@@ -850,7 +868,7 @@ export class BmClient {
|
|
|
850
868
|
].join("\n")
|
|
851
869
|
|
|
852
870
|
try {
|
|
853
|
-
await this.writeNote(title, content, "conversations")
|
|
871
|
+
await this.writeNote(title, content, "conversations", undefined, true)
|
|
854
872
|
log.debug(`created conversation note: ${title}`)
|
|
855
873
|
} catch (err) {
|
|
856
874
|
log.error("conversation index failed", err)
|
package/package.json
CHANGED
package/tools/write-note.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Type } from "@sinclair/typebox"
|
|
2
2
|
import type { OpenClawPluginApi } from "openclaw/plugin-sdk"
|
|
3
3
|
import type { BmClient } from "../bm-client.ts"
|
|
4
|
+
import { NoteAlreadyExistsError } from "../bm-client.ts"
|
|
4
5
|
import { log } from "../logger.ts"
|
|
5
6
|
|
|
6
7
|
export function registerWriteTool(
|
|
@@ -12,9 +13,9 @@ export function registerWriteTool(
|
|
|
12
13
|
name: "write_note",
|
|
13
14
|
label: "Write Note",
|
|
14
15
|
description:
|
|
15
|
-
"Create
|
|
16
|
-
"
|
|
17
|
-
"
|
|
16
|
+
"Create a note in the Basic Memory knowledge graph. " +
|
|
17
|
+
"If the note already exists, returns an error by default. " +
|
|
18
|
+
"Pass overwrite=true to replace, or use edit_note for incremental updates.",
|
|
18
19
|
parameters: Type.Object({
|
|
19
20
|
title: Type.String({ description: "Note title" }),
|
|
20
21
|
content: Type.String({
|
|
@@ -26,6 +27,12 @@ export function registerWriteTool(
|
|
|
26
27
|
description: "Target project name (defaults to current project)",
|
|
27
28
|
}),
|
|
28
29
|
),
|
|
30
|
+
overwrite: Type.Optional(
|
|
31
|
+
Type.Boolean({
|
|
32
|
+
description:
|
|
33
|
+
"Set to true to replace an existing note. Defaults to false.",
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
29
36
|
}),
|
|
30
37
|
async execute(
|
|
31
38
|
_toolCallId: string,
|
|
@@ -34,6 +41,7 @@ export function registerWriteTool(
|
|
|
34
41
|
content: string
|
|
35
42
|
folder: string
|
|
36
43
|
project?: string
|
|
44
|
+
overwrite?: boolean
|
|
37
45
|
},
|
|
38
46
|
) {
|
|
39
47
|
log.debug(`write_note: title=${params.title} folder=${params.folder}`)
|
|
@@ -44,6 +52,7 @@ export function registerWriteTool(
|
|
|
44
52
|
params.content,
|
|
45
53
|
params.folder,
|
|
46
54
|
params.project,
|
|
55
|
+
params.overwrite,
|
|
47
56
|
)
|
|
48
57
|
|
|
49
58
|
const msg = `Note saved: ${note.title} (${note.permalink})`
|
|
@@ -61,6 +70,22 @@ export function registerWriteTool(
|
|
|
61
70
|
},
|
|
62
71
|
}
|
|
63
72
|
} catch (err) {
|
|
73
|
+
if (err instanceof NoteAlreadyExistsError) {
|
|
74
|
+
const hint = [
|
|
75
|
+
`Note already exists: "${params.title}" (${err.permalink})`,
|
|
76
|
+
"",
|
|
77
|
+
"To update this note, use one of:",
|
|
78
|
+
` - edit_note("${err.permalink}", operation="append", content="...")`,
|
|
79
|
+
` - edit_note("${err.permalink}", operation="replace_section", section="...", content="...")`,
|
|
80
|
+
` - write_note("${params.title}", ..., overwrite=true) to fully replace`,
|
|
81
|
+
` - read_note("${err.permalink}") to inspect current content first`,
|
|
82
|
+
].join("\n")
|
|
83
|
+
|
|
84
|
+
return {
|
|
85
|
+
content: [{ type: "text" as const, text: hint }],
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
64
89
|
log.error("write_note failed", err)
|
|
65
90
|
return {
|
|
66
91
|
content: [
|