@basicmemory/openclaw-basic-memory 0.1.0-alpha.13 → 0.1.0-alpha.14

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 CHANGED
@@ -196,7 +196,7 @@ function isRecoverableConnectionError(err: unknown): boolean {
196
196
  )
197
197
  }
198
198
 
199
- function isNoteNotFoundError(err: unknown): boolean {
199
+ function _isNoteNotFoundError(err: unknown): boolean {
200
200
  const msg = getErrorMessage(err).toLowerCase()
201
201
  return (
202
202
  msg.includes("entity not found") ||
@@ -830,10 +830,6 @@ export class BmClient {
830
830
  return payload as unknown as MetadataSearchResult
831
831
  }
832
832
 
833
- private isNoteNotFoundError(err: unknown): boolean {
834
- return isNoteNotFoundError(err)
835
- }
836
-
837
833
  async indexConversation(
838
834
  userMessage: string,
839
835
  assistantResponse: string,
@@ -855,22 +851,33 @@ export class BmClient {
855
851
  "---",
856
852
  ].join("\n")
857
853
 
854
+ // Try append first — if it fails for ANY reason, fall through to create
858
855
  try {
859
856
  await this.editNote(title, "append", entry)
860
857
  log.debug(`appended conversation to: ${title}`)
858
+ return
861
859
  } catch (err) {
862
- if (!this.isNoteNotFoundError(err)) {
863
- log.error("conversation append failed", err)
864
- return
865
- }
860
+ log.debug(`append failed, will create: ${getErrorMessage(err)}`)
861
+ }
866
862
 
867
- const content = [`# Conversations ${dateStr}`, "", entry].join("\n")
868
- try {
869
- await this.writeNote(title, content, "conversations")
870
- log.debug(`created conversation note: ${title}`)
871
- } catch (createErr) {
872
- log.error("conversation index failed", createErr)
873
- }
863
+ // Create the note with frontmatter and first entry
864
+ const content = [
865
+ "---",
866
+ `title: Conversations ${dateStr}`,
867
+ "type: Conversation",
868
+ `date: "${dateStr}"`,
869
+ "---",
870
+ "",
871
+ `# Conversations ${dateStr}`,
872
+ "",
873
+ entry,
874
+ ].join("\n")
875
+
876
+ try {
877
+ await this.writeNote(title, content, "conversations")
878
+ log.debug(`created conversation note: ${title}`)
879
+ } catch (err) {
880
+ log.error("conversation index failed", err)
874
881
  }
875
882
  }
876
883
 
package/index.ts CHANGED
@@ -14,6 +14,7 @@ import {
14
14
  import { buildCaptureHandler } from "./hooks/capture.ts"
15
15
  import { buildRecallHandler } from "./hooks/recall.ts"
16
16
  import { initLogger, log } from "./logger.ts"
17
+ import { CONVERSATION_SCHEMA_CONTENT } from "./schema/conversation-schema.ts"
17
18
  import { TASK_SCHEMA_CONTENT } from "./schema/task-schema.ts"
18
19
  import { registerContextTool } from "./tools/build-context.ts"
19
20
  import { registerDeleteTool } from "./tools/delete-note.ts"
@@ -103,7 +104,9 @@ export default {
103
104
  'uv tool install "basic-memory @ git+https://github.com/basicmachines-co/basic-memory.git@main" --force',
104
105
  { encoding: "utf-8", timeout: 120_000, stdio: "pipe" },
105
106
  )
106
- log.info(`basic-memory installed: ${result.trim().split("\n").pop()}`)
107
+ log.info(
108
+ `basic-memory installed: ${result.trim().split("\n").pop()}`,
109
+ )
107
110
  // Verify it worked
108
111
  try {
109
112
  execSync(`command -v ${bmBin}`, { stdio: "ignore" })
@@ -113,7 +116,7 @@ export default {
113
116
  "bm installed but not found on PATH. You may need to add uv's bin directory to your PATH (typically ~/.local/bin).",
114
117
  )
115
118
  }
116
- } catch (uvErr) {
119
+ } catch (_uvErr) {
117
120
  log.error(
118
121
  "Cannot auto-install basic-memory: uv not found. " +
119
122
  "Install uv first (brew install uv, or curl -LsSf https://astral.sh/uv/install.sh | sh), " +
@@ -130,16 +133,21 @@ export default {
130
133
  await client.ensureProject(projectPath)
131
134
  log.debug(`project "${cfg.project}" at ${projectPath}`)
132
135
 
133
- // Seed Task schema if not already present
134
- try {
135
- await client.readNote("schema/Task")
136
- log.debug("Task schema already exists, skipping seed")
137
- } catch {
136
+ // Seed schemas if not already present
137
+ for (const [name, content] of [
138
+ ["Task", TASK_SCHEMA_CONTENT],
139
+ ["Conversation", CONVERSATION_SCHEMA_CONTENT],
140
+ ] as const) {
138
141
  try {
139
- await client.writeNote("Task", TASK_SCHEMA_CONTENT, "schema")
140
- log.debug("seeded Task schema note")
141
- } catch (err) {
142
- log.debug("Task schema seed failed (non-fatal)", err)
142
+ await client.readNote(`schema/${name}`)
143
+ log.debug(`${name} schema already exists, skipping seed`)
144
+ } catch {
145
+ try {
146
+ await client.writeNote(name, content, "schema")
147
+ log.debug(`seeded ${name} schema note`)
148
+ } catch (err) {
149
+ log.debug(`${name} schema seed failed (non-fatal)`, err)
150
+ }
143
151
  }
144
152
  }
145
153
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@basicmemory/openclaw-basic-memory",
3
- "version": "0.1.0-alpha.13",
3
+ "version": "0.1.0-alpha.14",
4
4
  "type": "module",
5
5
  "description": "Basic Memory plugin for OpenClaw — local-first knowledge graph for agent memory",
6
6
  "license": "MIT",
@@ -33,6 +33,7 @@
33
33
  "tools/write-note.ts",
34
34
  "types/openclaw.d.ts",
35
35
  "schema/task-schema.ts",
36
+ "schema/conversation-schema.ts",
36
37
  "skills/",
37
38
  "scripts/setup-bm.sh",
38
39
  "openclaw.plugin.json",
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Canonical Conversation schema note content, seeded into new projects on first startup.
3
+ * If the schema already exists (user may have customized it), seeding is skipped.
4
+ */
5
+ export const CONVERSATION_SCHEMA_CONTENT = `---
6
+ title: Conversation
7
+ type: schema
8
+ entity: Conversation
9
+ version: 1
10
+ schema:
11
+ date: "string, ISO date YYYY-MM-DD"
12
+ session_id?: "string, unique session identifier"
13
+ channel?: "string, where the conversation happened (webchat, telegram, discord, etc)"
14
+ participants?: "array, who was in the conversation"
15
+ topic?: "string, brief description of main topic"
16
+ summary?: "string, one-paragraph summary of key points"
17
+ key_decisions?: "array, decisions made during conversation"
18
+ action_items?: "array, things to do as a result"
19
+ settings:
20
+ validation: warn
21
+ ---
22
+
23
+ # Conversation
24
+
25
+ A record of a conversation session between the agent and user(s).
26
+
27
+ ## Observations
28
+ - [convention] Conversation files live in memory/conversations/ with format conversations-YYYY-MM-DD.md
29
+ - [convention] Messages are appended as the conversation progresses
30
+ - [convention] Summary and key_decisions populated at session end or by memory-reflect
31
+ - [convention] Skip routine greetings, heartbeat acks, and tool call details
32
+ - [convention] Focus on decisions, actions taken, and key context needed for continuity
33
+ `