mirror of
https://github.com/clawdbot/clawdbot.git
synced 2026-01-31 11:27:45 +01:00
Make memory more resilient to failure
This commit is contained in:
@@ -126,7 +126,7 @@ out to QMD for retrieval. Key points:
|
||||
- `paths[]`: add extra directories/files (`path`, optional `pattern`, optional
|
||||
stable `name`).
|
||||
- `sessions`: opt into session JSONL indexing (`enabled`, `retentionDays`,
|
||||
`exportDir`, `redactToolOutputs`—defaults to redacting tool payloads).
|
||||
`exportDir`).
|
||||
- `update`: controls refresh cadence (`interval`, `debounceMs`, `onBoot`).
|
||||
- `limits`: clamp recall payload (`maxResults`, `maxSnippetChars`,
|
||||
`maxInjectedChars`, `timeoutMs`).
|
||||
|
||||
@@ -264,7 +264,6 @@ const FIELD_LABELS: Record<string, string> = {
|
||||
"memory.qmd.sessions.enabled": "QMD Session Indexing",
|
||||
"memory.qmd.sessions.exportDir": "QMD Session Export Directory",
|
||||
"memory.qmd.sessions.retentionDays": "QMD Session Retention (days)",
|
||||
"memory.qmd.sessions.redactToolOutputs": "QMD Session Tool Redaction",
|
||||
"memory.qmd.update.interval": "QMD Update Interval",
|
||||
"memory.qmd.update.debounceMs": "QMD Update Debounce (ms)",
|
||||
"memory.qmd.update.onBoot": "QMD Update on Startup",
|
||||
@@ -576,8 +575,6 @@ const FIELD_HELP: Record<string, string> = {
|
||||
"Override directory for sanitized session exports before indexing.",
|
||||
"memory.qmd.sessions.retentionDays":
|
||||
"Retention window for exported sessions before pruning (default: unlimited).",
|
||||
"memory.qmd.sessions.redactToolOutputs":
|
||||
"Strip tool call payloads/results when exporting sessions (default: true).",
|
||||
"memory.qmd.update.interval":
|
||||
"How often the QMD sidecar refreshes indexes (duration string, default: 5m).",
|
||||
"memory.qmd.update.debounceMs":
|
||||
|
||||
@@ -29,7 +29,6 @@ export type MemoryQmdSessionConfig = {
|
||||
enabled?: boolean;
|
||||
exportDir?: string;
|
||||
retentionDays?: number;
|
||||
redactToolOutputs?: boolean;
|
||||
};
|
||||
|
||||
export type MemoryQmdUpdateConfig = {
|
||||
|
||||
@@ -45,7 +45,6 @@ const MemoryQmdSessionSchema = z
|
||||
enabled: z.boolean().optional(),
|
||||
exportDir: z.string().optional(),
|
||||
retentionDays: z.number().int().nonnegative().optional(),
|
||||
redactToolOutputs: z.boolean().optional(),
|
||||
})
|
||||
.strict();
|
||||
|
||||
|
||||
@@ -42,7 +42,6 @@ export type ResolvedQmdSessionConfig = {
|
||||
enabled: boolean;
|
||||
exportDir?: string;
|
||||
retentionDays?: number;
|
||||
redactToolOutputs: boolean;
|
||||
};
|
||||
|
||||
export type ResolvedQmdConfig = {
|
||||
@@ -147,12 +146,10 @@ function resolveSessionConfig(
|
||||
const exportDir = exportDirRaw ? resolvePath(exportDirRaw, workspaceDir) : undefined;
|
||||
const retentionDays =
|
||||
cfg?.retentionDays && cfg.retentionDays > 0 ? Math.floor(cfg.retentionDays) : undefined;
|
||||
const redactToolOutputs = cfg?.redactToolOutputs !== false;
|
||||
return {
|
||||
enabled,
|
||||
exportDir,
|
||||
retentionDays,
|
||||
redactToolOutputs,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -225,7 +225,7 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
source: doc.source,
|
||||
});
|
||||
}
|
||||
return results.slice(0, limit);
|
||||
return this.clampResultsByInjectedChars(results.slice(0, limit));
|
||||
}
|
||||
|
||||
async sync(params?: {
|
||||
@@ -609,4 +609,24 @@ export class QmdMemoryManager implements MemorySearchManager {
|
||||
const next = candidate.endsWith(path.sep) ? candidate : `${candidate}${path.sep}`;
|
||||
return next.startsWith(normalizedRoot);
|
||||
}
|
||||
|
||||
private clampResultsByInjectedChars(results: MemorySearchResult[]): MemorySearchResult[] {
|
||||
const budget = this.qmd.limits.maxInjectedChars;
|
||||
if (!budget || budget <= 0) return results;
|
||||
let remaining = budget;
|
||||
const clamped: MemorySearchResult[] = [];
|
||||
for (const entry of results) {
|
||||
if (remaining <= 0) break;
|
||||
const snippet = entry.snippet ?? "";
|
||||
if (snippet.length <= remaining) {
|
||||
clamped.push(entry);
|
||||
remaining -= snippet.length;
|
||||
} else {
|
||||
const trimmed = snippet.slice(0, Math.max(0, remaining));
|
||||
clamped.push({ ...entry, snippet: trimmed });
|
||||
break;
|
||||
}
|
||||
}
|
||||
return clamped;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,10 +111,12 @@ class FallbackMemoryManager implements MemorySearchManager {
|
||||
return this.deps.primary.status();
|
||||
}
|
||||
const fallbackStatus = this.fallback?.status();
|
||||
const fallbackInfo = { from: "qmd", reason: this.lastError ?? "unknown" };
|
||||
if (fallbackStatus) {
|
||||
const custom = fallbackStatus.custom ?? {};
|
||||
return {
|
||||
...fallbackStatus,
|
||||
fallback: fallbackInfo,
|
||||
custom: {
|
||||
...custom,
|
||||
fallback: { disabled: true, reason: this.lastError ?? "unknown" },
|
||||
@@ -125,6 +127,7 @@ class FallbackMemoryManager implements MemorySearchManager {
|
||||
const custom = primaryStatus.custom ?? {};
|
||||
return {
|
||||
...primaryStatus,
|
||||
fallback: fallbackInfo,
|
||||
custom: {
|
||||
...custom,
|
||||
fallback: { disabled: true, reason: this.lastError ?? "unknown" },
|
||||
|
||||
@@ -27,6 +27,7 @@ export type MemoryProviderStatus = {
|
||||
workspaceDir?: string;
|
||||
dbPath?: string;
|
||||
sources?: MemorySource[];
|
||||
sourceCounts?: Array<{ source: MemorySource; files: number; chunks: number }>;
|
||||
cache?: { enabled: boolean; entries?: number; maxEntries?: number };
|
||||
fts?: { enabled: boolean; available: boolean; error?: string };
|
||||
fallback?: { from: string; reason?: string };
|
||||
|
||||
Reference in New Issue
Block a user