Skip to content

Commit b4618c4

Browse files
fix(memory): retry reindex on socket errors
1 parent d065230 commit b4618c4

2 files changed

Lines changed: 1 addition & 56 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ Docs: https://docs.openclaw.ai
2525
- Auto-reply/queue: treat reset-triggered `/new` and `/reset` turns as interrupt runs across active-run queue handling, so steer/followup modes cannot delay a fresh session behind existing work. Fixes #74093. (#74144) Thanks @ruji9527 and @yelog.
2626
- Cron: preserve manual `cron.run` IDs in `cron.runs` history so manual run acknowledgements can be correlated with finished run records. Fixes #76276.
2727
- CLI/devices: request `operator.admin` for `openclaw devices approve <requestId>` only when the exact pending device request would mint or inherit admin-scoped operator access, while keeping lower-scope approvals on the pairing scope.
28-
- Memory/embedding: broaden the embedding reindex retry classifier to include transient socket-layer errors (`fetch failed`, `ECONNRESET`, `socket hang up`, `UND_ERR_*`, `closed`) so memory reindex survives provider network hiccups instead of aborting mid-run. Related #56815, #44166.
28+
- Memory/embedding: broaden the embedding reindex retry classifier to include transient socket-layer errors (`fetch failed`, `ECONNRESET`, `socket hang up`, `UND_ERR_*`, `closed`) so memory reindex survives provider network hiccups instead of aborting mid-run. Related #56815, #44166. (#76311) Thanks @buyitsydney.
2929
- Gateway: keep directly requested plugin tools invokable under restrictive tool profiles while preserving explicit deny lists and the HTTP safety deny list, preventing catalog/invoke mismatches that surface as "Tool not available". Thanks @BunsDev.
3030
- Gateway/update: allow beta binaries to refresh gateway services when the config was last written by the matching stable release version, avoiding false newer-config downgrade blocks during beta channel updates.
3131
- Channels: keep Matrix and Mattermost bundled in the core package instead of advertising external npm installs before those channels are cut over. Thanks @vincentkoc.

packages/memory-host-sdk/src/host/session-files.test.ts

Lines changed: 0 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import fsSync from "node:fs";
2-
import fs from "node:fs/promises";
32
import os from "node:os";
43
import path from "node:path";
54
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from "vitest";
@@ -101,7 +100,6 @@ describe("buildSessionEntry", () => {
101100
// Content line 2 → JSONL line 7 (the second user message)
102101
expect(entry!.lineMap).toBeDefined();
103102
expect(entry!.lineMap).toEqual([4, 6, 7]);
104-
expect(entry!.messageTimestampsMs).toEqual([0, 0, 0]);
105103
});
106104

107105
it("returns empty lineMap when no messages are found", async () => {
@@ -116,7 +114,6 @@ describe("buildSessionEntry", () => {
116114
expect(entry).not.toBeNull();
117115
expect(entry!.content).toBe("");
118116
expect(entry!.lineMap).toEqual([]);
119-
expect(entry!.messageTimestampsMs).toEqual([]);
120117
});
121118

122119
it("skips deleted and checkpoint transcripts for dreaming ingestion", async () => {
@@ -157,58 +154,6 @@ describe("buildSessionEntry", () => {
157154
const entry = await buildSessionEntry(filePath);
158155
expect(entry).not.toBeNull();
159156
expect(entry!.lineMap).toEqual([3, 5]);
160-
expect(entry!.messageTimestampsMs).toEqual([0, 0]);
161-
});
162-
163-
it("captures message timestamps when present", async () => {
164-
const jsonlLines = [
165-
JSON.stringify({
166-
type: "message",
167-
timestamp: "2026-04-05T10:00:00.000Z",
168-
message: { role: "user", content: "First" },
169-
}),
170-
JSON.stringify({
171-
type: "message",
172-
message: {
173-
role: "assistant",
174-
timestamp: "2026-04-05T10:01:00.000Z",
175-
content: "Second",
176-
},
177-
}),
178-
];
179-
const filePath = path.join(tmpDir, "timestamps.jsonl");
180-
await fs.writeFile(filePath, jsonlLines.join("\n"));
181-
182-
const entry = await buildSessionEntry(filePath);
183-
expect(entry).not.toBeNull();
184-
expect(entry!.messageTimestampsMs).toEqual([
185-
Date.parse("2026-04-05T10:00:00.000Z"),
186-
Date.parse("2026-04-05T10:01:00.000Z"),
187-
]);
188-
});
189-
190-
it("flags dreaming narrative transcripts from bootstrap metadata", async () => {
191-
const jsonlLines = [
192-
JSON.stringify({
193-
type: "custom",
194-
customType: "openclaw:bootstrap-context:full",
195-
data: {
196-
runId: "dreaming-narrative-light-1775894400455",
197-
sessionId: "sid-1",
198-
},
199-
}),
200-
JSON.stringify({
201-
type: "message",
202-
message: { role: "user", content: "Write a dream diary entry from these memory fragments" },
203-
}),
204-
];
205-
const filePath = path.join(tmpDir, "dreaming-session.jsonl");
206-
await fs.writeFile(filePath, jsonlLines.join("\n"));
207-
208-
const entry = await buildSessionEntry(filePath);
209-
210-
expect(entry).not.toBeNull();
211-
expect(entry?.generatedByDreamingNarrative).toBe(true);
212157
});
213158

214159
it("strips inbound metadata when a user envelope is split across text blocks", async () => {

0 commit comments

Comments
 (0)