Files
basicmachines-co-basic-memory/integrations/openclaw/tools/write-note.ts
2026-05-30 14:16:04 -05:00

114 lines
3.5 KiB
TypeScript

import { Type } from "@sinclair/typebox"
import type { OpenClawPluginApi } from "openclaw/plugin-sdk/plugin-entry"
import type { BmClient } from "../bm-client.ts"
import { NoteAlreadyExistsError } from "../bm-client.ts"
import { log } from "../logger.ts"
export function registerWriteTool(
api: OpenClawPluginApi,
client: BmClient,
): void {
api.registerTool(
{
name: "write_note",
label: "Write Note",
description:
"Create a note in the Basic Memory knowledge graph. " +
"If the note already exists, returns an error by default. " +
"Pass overwrite=true to replace, or use edit_note for incremental updates.",
parameters: Type.Object({
title: Type.String({ description: "Note title" }),
content: Type.String({
description: "Note content in Markdown format",
}),
folder: Type.String({ description: "Folder to write the note in" }),
project: Type.Optional(
Type.String({
description: "Target project name (defaults to current project)",
}),
),
overwrite: Type.Optional(
Type.Boolean({
description:
"Set to true to replace an existing note. Defaults to false.",
}),
),
}),
async execute(
_toolCallId: string,
params: {
title: string
content: string
folder: string
project?: string
overwrite?: boolean
},
) {
log.debug(`write_note: title=${params.title} folder=${params.folder}`)
try {
const note = await client.writeNote(
params.title,
params.content,
params.folder,
params.project,
params.overwrite,
)
const msg = `Note saved: ${note.title} (${note.permalink})`
return {
content: [
{
type: "text" as const,
text: msg,
},
],
details: {
title: note.title,
permalink: note.permalink,
file_path: note.file_path,
},
}
} catch (err) {
if (err instanceof NoteAlreadyExistsError) {
const hint = [
`Note already exists: "${params.title}" (${err.permalink})`,
"",
"To update this note, use one of:",
` - edit_note("${err.permalink}", operation="append", content="...")`,
` - edit_note("${err.permalink}", operation="replace_section", section="...", content="...")`,
` - write_note("${params.title}", ..., overwrite=true) to fully replace`,
` - read_note("${err.permalink}") to inspect current content first`,
].join("\n")
return {
content: [{ type: "text" as const, text: hint }],
details: {
title: params.title,
permalink: err.permalink,
error: "note_already_exists",
},
}
}
log.error("write_note failed", err)
return {
content: [
{
type: "text" as const,
text: "Failed to write note. Is Basic Memory running? Check logs for details.",
},
],
details: {
title: params.title,
folder: params.folder,
error: "write_note_failed",
},
}
}
},
},
{ name: "write_note" },
)
}