mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-31 20:01:42 +00:00
Cap Dreaming short-term recall stores so repeated recall recording, repair, and promotion application cannot grow the JSON artifact without bound. The fix keeps full normalized snippets for recall identity and contamination checks before truncating persisted snippets, exposes the new overflow audit code through the SDK facade, and adds regression coverage for recording, repair, promotion rehydration, and deterministic retention ties. Fixes #87095. Verification: - OPENCLAW_VITEST_MAX_WORKERS=1 node scripts/run-vitest.mjs extensions/memory-core/src/short-term-promotion.test.ts src/commands/doctor-memory-search.test.ts src/plugin-sdk/memory-core-engine-runtime.test.ts - pnpm tsgo:prod - pnpm check:test-types - pnpm lint --threads=8 - git diff --check - .agents/skills/autoreview/scripts/autoreview --mode branch --base origin/main - PR CI run 26594527697: unrelated current-main failures only in checks-node-agentic-plugin-sdk and checks-node-agentic-agents; same failures reproduced on main run 26594198639. Co-authored-by: ai-hpc <mail.speedy.hpc@hotmail.com>
177 lines
5.8 KiB
TypeScript
177 lines
5.8 KiB
TypeScript
/**
|
|
* @deprecated Public SDK subpath has no bundled extension production imports.
|
|
* Prefer vendor-neutral memory-host SDK subpaths for new plugin code.
|
|
*/
|
|
import type { OpenClawConfig } from "../config/types.js";
|
|
import {
|
|
createLazyFacadeObjectValue,
|
|
loadActivatedBundledPluginPublicSurfaceModuleSync,
|
|
} from "./facade-runtime.js";
|
|
import type { MemorySearchManager } from "./memory-core-host-engine-storage.js";
|
|
|
|
export type BuiltinMemoryEmbeddingProviderDoctorMetadata = {
|
|
providerId: string;
|
|
authProviderId: string;
|
|
envVars: string[];
|
|
transport: "local" | "remote";
|
|
autoSelectPriority?: number;
|
|
};
|
|
|
|
export type DreamingArtifactsAuditIssue = {
|
|
severity: "warn" | "error";
|
|
code:
|
|
| "dreaming-session-corpus-unreadable"
|
|
| "dreaming-session-corpus-self-ingested"
|
|
| "dreaming-session-ingestion-unreadable"
|
|
| "dreaming-diary-unreadable";
|
|
message: string;
|
|
fixable: boolean;
|
|
};
|
|
|
|
export type DreamingArtifactsAuditSummary = {
|
|
dreamsPath?: string;
|
|
sessionCorpusDir: string;
|
|
sessionCorpusFileCount: number;
|
|
suspiciousSessionCorpusFileCount: number;
|
|
suspiciousSessionCorpusLineCount: number;
|
|
sessionIngestionPath: string;
|
|
sessionIngestionExists: boolean;
|
|
issues: DreamingArtifactsAuditIssue[];
|
|
};
|
|
|
|
export type RepairDreamingArtifactsResult = {
|
|
changed: boolean;
|
|
archiveDir?: string;
|
|
archivedDreamsDiary: boolean;
|
|
archivedSessionCorpus: boolean;
|
|
archivedSessionIngestion: boolean;
|
|
archivedPaths: string[];
|
|
warnings: string[];
|
|
};
|
|
|
|
export type ShortTermAuditIssue = {
|
|
severity: "warn" | "error";
|
|
code:
|
|
| "recall-store-unreadable"
|
|
| "recall-store-empty"
|
|
| "recall-store-invalid"
|
|
| "recall-store-over-limit"
|
|
| "recall-lock-stale"
|
|
| "recall-lock-unreadable"
|
|
| "qmd-index-missing"
|
|
| "qmd-index-empty"
|
|
| "qmd-collections-empty";
|
|
message: string;
|
|
fixable: boolean;
|
|
};
|
|
|
|
export type ShortTermAuditSummary = {
|
|
storePath: string;
|
|
lockPath: string;
|
|
updatedAt?: string;
|
|
exists: boolean;
|
|
entryCount: number;
|
|
promotedCount: number;
|
|
spacedEntryCount: number;
|
|
conceptTaggedEntryCount: number;
|
|
conceptTagScripts?: Record<string, unknown>;
|
|
invalidEntryCount: number;
|
|
issues: ShortTermAuditIssue[];
|
|
qmd?:
|
|
| {
|
|
dbPath?: string;
|
|
collections?: number;
|
|
dbBytes?: number;
|
|
}
|
|
| undefined;
|
|
};
|
|
|
|
export type RepairShortTermPromotionArtifactsResult = {
|
|
changed: boolean;
|
|
removedInvalidEntries: number;
|
|
removedOverflowEntries?: number;
|
|
rewroteStore: boolean;
|
|
removedStaleLock: boolean;
|
|
};
|
|
|
|
type MemoryIndexManagerFacade = {
|
|
get(params: {
|
|
cfg: OpenClawConfig;
|
|
agentId: string;
|
|
purpose?: "default" | "status";
|
|
}): Promise<MemorySearchManager | null>;
|
|
};
|
|
|
|
type FacadeModule = {
|
|
auditShortTermPromotionArtifacts: (params: {
|
|
workspaceDir: string;
|
|
qmd?: {
|
|
dbPath?: string;
|
|
collections?: number;
|
|
};
|
|
}) => Promise<ShortTermAuditSummary>;
|
|
auditDreamingArtifacts: (params: {
|
|
workspaceDir: string;
|
|
}) => Promise<DreamingArtifactsAuditSummary>;
|
|
getBuiltinMemoryEmbeddingProviderDoctorMetadata: (
|
|
providerId: string,
|
|
) => BuiltinMemoryEmbeddingProviderDoctorMetadata | null;
|
|
getMemorySearchManager: (params: {
|
|
cfg: OpenClawConfig;
|
|
agentId: string;
|
|
purpose?: "default" | "status";
|
|
}) => Promise<{
|
|
manager: MemorySearchManager | null;
|
|
error?: string;
|
|
}>;
|
|
listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata: () => Array<BuiltinMemoryEmbeddingProviderDoctorMetadata>;
|
|
MemoryIndexManager: MemoryIndexManagerFacade;
|
|
repairShortTermPromotionArtifacts: (params: {
|
|
workspaceDir: string;
|
|
}) => Promise<RepairShortTermPromotionArtifactsResult>;
|
|
repairDreamingArtifacts: (params: {
|
|
workspaceDir: string;
|
|
archiveDiary?: boolean;
|
|
now?: Date;
|
|
}) => Promise<RepairDreamingArtifactsResult>;
|
|
};
|
|
|
|
function loadFacadeModule(): FacadeModule {
|
|
return loadActivatedBundledPluginPublicSurfaceModuleSync<FacadeModule>({
|
|
dirName: "memory-core",
|
|
artifactBasename: "runtime-api.js",
|
|
});
|
|
}
|
|
export const auditShortTermPromotionArtifacts: FacadeModule["auditShortTermPromotionArtifacts"] = ((
|
|
...args
|
|
) =>
|
|
loadFacadeModule()["auditShortTermPromotionArtifacts"](
|
|
...args,
|
|
)) as FacadeModule["auditShortTermPromotionArtifacts"];
|
|
export const auditDreamingArtifacts: FacadeModule["auditDreamingArtifacts"] = ((...args) =>
|
|
loadFacadeModule()["auditDreamingArtifacts"](...args)) as FacadeModule["auditDreamingArtifacts"];
|
|
export const getBuiltinMemoryEmbeddingProviderDoctorMetadata: FacadeModule["getBuiltinMemoryEmbeddingProviderDoctorMetadata"] =
|
|
((...args) =>
|
|
loadFacadeModule()["getBuiltinMemoryEmbeddingProviderDoctorMetadata"](
|
|
...args,
|
|
)) as FacadeModule["getBuiltinMemoryEmbeddingProviderDoctorMetadata"];
|
|
export const getMemorySearchManager: FacadeModule["getMemorySearchManager"] = ((...args) =>
|
|
loadFacadeModule()["getMemorySearchManager"](...args)) as FacadeModule["getMemorySearchManager"];
|
|
export const listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata: FacadeModule["listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata"] =
|
|
((...args) =>
|
|
loadFacadeModule()["listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata"](
|
|
...args,
|
|
)) as FacadeModule["listBuiltinAutoSelectMemoryEmbeddingProviderDoctorMetadata"];
|
|
export const MemoryIndexManager: FacadeModule["MemoryIndexManager"] = createLazyFacadeObjectValue(
|
|
() => loadFacadeModule()["MemoryIndexManager"] as object,
|
|
) as FacadeModule["MemoryIndexManager"];
|
|
export const repairShortTermPromotionArtifacts: FacadeModule["repairShortTermPromotionArtifacts"] =
|
|
((...args) =>
|
|
loadFacadeModule()["repairShortTermPromotionArtifacts"](
|
|
...args,
|
|
)) as FacadeModule["repairShortTermPromotionArtifacts"];
|
|
export const repairDreamingArtifacts: FacadeModule["repairDreamingArtifacts"] = ((...args) =>
|
|
loadFacadeModule()["repairDreamingArtifacts"](
|
|
...args,
|
|
)) as FacadeModule["repairDreamingArtifacts"];
|