Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/Java/Openclaw/extensions/memory-wiki/src/   (KI Agentensystem Version 22©)  Datei vom 26.3.2026 mit Größe 18 kB image not shown  

Quelle  query.test.ts

  Sprache: JAVA
 

Spracherkennung für: .ts vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

import fs from "node:fs/promises";
import os from "node:os";
import path from "node:path";
import { afterAll, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import type { OpenClawConfig } from "../api.js";
import { compileMemoryWikiVault } from "./compile.js";
import type { MemoryWikiPluginConfig } from "./config.js";
import { renderWikiMarkdown } from "./markdown.js";
import { getMemoryWikiPage, searchMemoryWiki } from "./query.js";
import { createMemoryWikiTestHarness } from "./test-helpers.js";

const { getActiveMemorySearchManagerMock, resolveDefaultAgentIdMock, resolveSessionAgentIdMock } =
  vi.hoisted(() => ({
    getActiveMemorySearchManagerMock: vi.fn(),
    resolveDefaultAgentIdMock: vi.fn(() => "main"),
    resolveSessionAgentIdMock: vi.fn(({ sessionKey }: { sessionKey?: string }) =>
      sessionKey === "agent:secondary:thread" ? "secondary" : "main",
    ),
  }));

vi.mock("openclaw/plugin-sdk/memory-host-search", () => ({
  getActiveMemorySearchManager: getActiveMemorySearchManagerMock,
}));

vi.mock("openclaw/plugin-sdk/memory-host-core", () => ({
  resolveDefaultAgentId: resolveDefaultAgentIdMock,
  resolveSessionAgentId: resolveSessionAgentIdMock,
}));

const { createVault } = createMemoryWikiTestHarness();
let suiteRoot = "";
let caseIndex = 0;

beforeEach(() => {
  getActiveMemorySearchManagerMock.mockReset();
  getActiveMemorySearchManagerMock.mockResolvedValue({ manager: null, error: "unavailable" });
  resolveDefaultAgentIdMock.mockClear();
  resolveSessionAgentIdMock.mockClear();
});

beforeAll(async () => {
  suiteRoot = await fs.mkdtemp(path.join(os.tmpdir(), "memory-wiki-query-suite-"));
});

afterAll(async () => {
  if (suiteRoot) {
    await fs.rm(suiteRoot, { recursive: true, force: true });
  }
});

async function createQueryVault(options?: {
  config?: MemoryWikiPluginConfig;
  initialize?: boolean;
}) {
  return createVault({
    prefix: "memory-wiki-query-",
    rootDir: path.join(suiteRoot, `case-${caseIndex++}`),
    initialize: options?.initialize,
    config: options?.config,
  });
}

function createAppConfig(): OpenClawConfig {
  return {
    agents: {
      list: [{ id: "main", default: true }],
    },
  } as OpenClawConfig;
}

function createMemoryManager(overrides?: {
  searchResults?: Array<{
    path: string;
    startLine: number;
    endLine: number;
    score: number;
    snippet: string;
    source: "memory" | "sessions";
    citation?: string;
  }>;
  readResult?: { text: string; path: string };
}) {
  return {
    search: vi.fn().mockResolvedValue(overrides?.searchResults ?? []),
    readFile: vi.fn().mockImplementation(async () => {
      if (!overrides?.readResult) {
        throw new Error("missing");
      }
      return overrides.readResult;
    }),
    status: vi.fn().mockReturnValue({ backend: "builtin", provider: "builtin" }),
    probeEmbeddingAvailability: vi.fn().mockResolvedValue({ ok: true }),
    probeVectorAvailability: vi.fn().mockResolvedValue(false),
    close: vi.fn().mockResolvedValue(undefined),
  };
}

describe("searchMemoryWiki", () => {
  it("finds wiki pages by title and body", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: { pageType: "source", id: "source.alpha", title: "Alpha Source" },
        body: "# Alpha Source\n\nalpha body text\n",
      }),
      "utf8",
    );

    const results = await searchMemoryWiki({ config, query: "alpha" });

    expect(results).toHaveLength(1);
    expect(results[0]?.corpus).toBe("wiki");
    expect(results[0]?.path).toBe("sources/alpha.md");
    expect(getActiveMemorySearchManagerMock).not.toHaveBeenCalled();
  });

  it("finds wiki pages by structured claim text and surfaces the claim as the snippet", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "entities", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: {
          pageType: "entity",
          id: "entity.alpha",
          title: "Alpha",
          claims: [
            {
              id: "claim.alpha.postgres",
              text: "Alpha uses PostgreSQL for production writes.",
              status: "supported",
              confidence: 0.91,
              evidence: [{ sourceId: "source.alpha", lines: "12-18" }],
            },
          ],
        },
        body: "# Alpha\n\nsummary without the query phrase\n",
      }),
      "utf8",
    );

    const results = await searchMemoryWiki({ config, query: "postgresql" });

    expect(results).toHaveLength(1);
    expect(results[0]).toMatchObject({
      corpus: "wiki",
      path: "entities/alpha.md",
      snippet: "Alpha uses PostgreSQL for production writes.",
    });
  });

  it("ranks fresh supported claims ahead of stale contested claims", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "entities", "alpha-fresh.md"),
      renderWikiMarkdown({
        frontmatter: {
          pageType: "entity",
          id: "entity.alpha.fresh",
          title: "Alpha Fresh",
          updatedAt: "2026-04-01T00:00:00.000Z",
          claims: [
            {
              id: "claim.alpha.db.fresh",
              text: "Alpha uses PostgreSQL for production writes.",
              status: "supported",
              confidence: 0.91,
              evidence: [
                {
                  sourceId: "source.alpha",
                  lines: "4-7",
                  updatedAt: "2026-04-01T00:00:00.000Z",
                },
              ],
            },
          ],
        },
        body: "# Alpha Fresh\n\nsummary without the keyword\n",
      }),
      "utf8",
    );
    await fs.writeFile(
      path.join(rootDir, "entities", "alpha-stale.md"),
      renderWikiMarkdown({
        frontmatter: {
          pageType: "entity",
          id: "entity.alpha.stale",
          title: "Alpha Stale",
          updatedAt: "2025-10-01T00:00:00.000Z",
          claims: [
            {
              id: "claim.alpha.db.stale",
              text: "Alpha uses PostgreSQL for production writes.",
              status: "contested",
              confidence: 0.92,
              evidence: [
                {
                  sourceId: "source.alpha.old",
                  lines: "1-2",
                  updatedAt: "2025-10-01T00:00:00.000Z",
                },
              ],
            },
          ],
        },
        body: "# Alpha Stale\n\nsummary without the keyword\n",
      }),
      "utf8",
    );

    const results = await searchMemoryWiki({ config, query: "postgresql" });

    expect(results).toHaveLength(2);
    expect(results[0]?.path).toBe("entities/alpha-fresh.md");
    expect(results[1]?.path).toBe("entities/alpha-stale.md");
  });

  it("surfaces bridge provenance for imported source pages", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "bridge-alpha.md"),
      renderWikiMarkdown({
        frontmatter: {
          pageType: "source",
          id: "source.bridge.alpha",
          title: "Bridge Alpha",
          sourceType: "memory-bridge",
          sourcePath: "/tmp/workspace/MEMORY.md",
          bridgeRelativePath: "MEMORY.md",
          bridgeWorkspaceDir: "/tmp/workspace",
          updatedAt: "2026-04-05T12:00:00.000Z",
        },
        body: "# Bridge Alpha\n\nalpha bridge body\n",
      }),
      "utf8",
    );

    const results = await searchMemoryWiki({ config, query: "alpha" });

    expect(results).toHaveLength(1);
    expect(results[0]).toMatchObject({
      corpus: "wiki",
      sourceType: "memory-bridge",
      sourcePath: "/tmp/workspace/MEMORY.md",
      provenanceLabel: "bridge: MEMORY.md",
      updatedAt: "2026-04-05T12:00:00.000Z",
    });
  });

  it("includes active memory results when shared search and all corpora are enabled", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "shared", corpus: "all" },
      },
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: { pageType: "source", id: "source.alpha", title: "Alpha Source" },
        body: "# Alpha Source\n\nalpha body text\n",
      }),
      "utf8",
    );
    const manager = createMemoryManager({
      searchResults: [
        {
          path: "MEMORY.md",
          startLine: 4,
          endLine: 8,
          score: 42,
          snippet: "alpha durable memory",
          source: "memory",
          citation: "MEMORY.md#L4-L8",
        },
      ],
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    const results = await searchMemoryWiki({
      config,
      appConfig: createAppConfig(),
      query: "alpha",
      maxResults: 5,
    });

    expect(results).toHaveLength(2);
    expect(results.some((result) => result.corpus === "wiki")).toBe(true);
    expect(results.some((result) => result.corpus === "memory")).toBe(true);
    expect(manager.search).toHaveBeenCalledWith("alpha", { maxResults: 5 });
    expect(getActiveMemorySearchManagerMock).toHaveBeenCalledWith({
      cfg: createAppConfig(),
      agentId: "main",
    });
  });

  it("uses the active session agent for shared memory search", async () => {
    const { config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "shared", corpus: "memory" },
      },
    });
    const manager = createMemoryManager({
      searchResults: [
        {
          path: "memory/2026-04-07.md",
          startLine: 1,
          endLine: 2,
          score: 1,
          snippet: "secondary agent memory",
          source: "memory",
        },
      ],
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    await searchMemoryWiki({
      config,
      appConfig: createAppConfig(),
      agentSessionKey: "agent:secondary:thread",
      query: "secondary",
    });

    expect(resolveSessionAgentIdMock).toHaveBeenCalledWith({
      sessionKey: "agent:secondary:thread",
      config: createAppConfig(),
    });
    expect(getActiveMemorySearchManagerMock).toHaveBeenCalledWith({
      cfg: createAppConfig(),
      agentId: "secondary",
    });
  });

  it("allows per-call corpus overrides without changing config defaults", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "shared", corpus: "wiki" },
      },
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: { pageType: "source", id: "source.alpha", title: "Alpha Source" },
        body: "# Alpha Source\n\nalpha body text\n",
      }),
      "utf8",
    );
    const manager = createMemoryManager({
      searchResults: [
        {
          path: "MEMORY.md",
          startLine: 10,
          endLine: 12,
          score: 99,
          snippet: "memory-only alpha",
          source: "memory",
        },
      ],
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    const memoryOnly = await searchMemoryWiki({
      config,
      appConfig: createAppConfig(),
      query: "alpha",
      searchCorpus: "memory",
    });

    expect(memoryOnly).toHaveLength(1);
    expect(memoryOnly[0]?.corpus).toBe("memory");
    expect(manager.search).toHaveBeenCalledWith("alpha", { maxResults: 10 });
  });

  it("keeps memory search disabled when the backend is local", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "local", corpus: "all" },
      },
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: { pageType: "source", id: "source.alpha", title: "Alpha Source" },
        body: "# Alpha Source\n\nalpha only wiki\n",
      }),
      "utf8",
    );
    const manager = createMemoryManager({
      searchResults: [
        {
          path: "MEMORY.md",
          startLine: 1,
          endLine: 2,
          score: 50,
          snippet: "alpha memory",
          source: "memory",
        },
      ],
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    const results = await searchMemoryWiki({
      config,
      appConfig: createAppConfig(),
      query: "alpha",
    });

    expect(results).toHaveLength(1);
    expect(results[0]?.corpus).toBe("wiki");
    expect(manager.search).not.toHaveBeenCalled();
  });
});

describe("getMemoryWikiPage", () => {
  it("reads wiki pages by relative path and slices line ranges", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: { pageType: "source", id: "source.alpha", title: "Alpha Source" },
        body: "# Alpha Source\n\nline one\nline two\nline three\n",
      }),
      "utf8",
    );

    const result = await getMemoryWikiPage({
      config,
      lookup: "sources/alpha.md",
      fromLine: 4,
      lineCount: 2,
    });

    expect(result?.corpus).toBe("wiki");
    expect(result?.path).toBe("sources/alpha.md");
    expect(result?.content).toContain("line one");
    expect(result?.content).toContain("line two");
    expect(result?.content).not.toContain("line three");
    expect(result?.totalLines).toBe(7);
    expect(result?.truncated).toBe(true);
  });

  it("resolves compiled claim ids back to the owning page", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "entities", "alpha.md"),
      renderWikiMarkdown({
        frontmatter: {
          pageType: "entity",
          id: "entity.alpha",
          title: "Alpha",
          claims: [
            {
              id: "claim.alpha.db",
              text: "Alpha uses PostgreSQL for production writes.",
              status: "supported",
              evidence: [{ sourceId: "source.alpha", lines: "1-2" }],
            },
          ],
        },
        body: "# Alpha\n\nline one\nline two\n",
      }),
      "utf8",
    );
    await compileMemoryWikiVault(config);

    const result = await getMemoryWikiPage({
      config,
      lookup: "claim.alpha.db",
    });

    expect(result).toMatchObject({
      corpus: "wiki",
      path: "entities/alpha.md",
      title: "Alpha",
      id: "entity.alpha",
    });
    expect(result?.content).toContain("line one");
  });

  it("returns provenance for imported wiki source pages", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "unsafe-alpha.md"),
      renderWikiMarkdown({
        frontmatter: {
          pageType: "source",
          id: "source.unsafe.alpha",
          title: "Unsafe Alpha",
          sourceType: "memory-unsafe-local",
          provenanceMode: "unsafe-local",
          sourcePath: "/tmp/private/alpha.md",
          unsafeLocalConfiguredPath: "/tmp/private",
          unsafeLocalRelativePath: "alpha.md",
          updatedAt: "2026-04-05T13:00:00.000Z",
        },
        body: "# Unsafe Alpha\n\nsecret alpha\n",
      }),
      "utf8",
    );

    const result = await getMemoryWikiPage({
      config,
      lookup: "sources/unsafe-alpha.md",
    });

    expect(result).toMatchObject({
      corpus: "wiki",
      path: "sources/unsafe-alpha.md",
      sourceType: "memory-unsafe-local",
      provenanceMode: "unsafe-local",
      sourcePath: "/tmp/private/alpha.md",
      provenanceLabel: "unsafe-local: alpha.md",
      updatedAt: "2026-04-05T13:00:00.000Z",
    });
  });

  it("falls back to active memory reads when memory corpus is selected", async () => {
    const { config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "shared", corpus: "memory" },
      },
    });
    const manager = createMemoryManager({
      readResult: {
        path: "MEMORY.md",
        text: "durable alpha memory\nline two",
      },
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    const result = await getMemoryWikiPage({
      config,
      appConfig: createAppConfig(),
      lookup: "MEMORY.md",
      fromLine: 2,
      lineCount: 2,
    });

    expect(result).toEqual({
      corpus: "memory",
      path: "MEMORY.md",
      title: "MEMORY",
      kind: "memory",
      content: "durable alpha memory\nline two",
      fromLine: 2,
      lineCount: 2,
    });
    expect(manager.readFile).toHaveBeenCalledWith({
      relPath: "MEMORY.md",
      from: 2,
      lines: 2,
    });
  });

  it("uses the active session agent for shared memory reads", async () => {
    const { config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "shared", corpus: "memory" },
      },
    });
    const manager = createMemoryManager({
      readResult: {
        path: "MEMORY.md",
        text: "secondary memory line",
      },
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    const result = await getMemoryWikiPage({
      config,
      appConfig: createAppConfig(),
      agentSessionKey: "agent:secondary:thread",
      lookup: "MEMORY.md",
    });

    expect(result?.corpus).toBe("memory");
    expect(resolveSessionAgentIdMock).toHaveBeenCalledWith({
      sessionKey: "agent:secondary:thread",
      config: createAppConfig(),
    });
    expect(getActiveMemorySearchManagerMock).toHaveBeenCalledWith({
      cfg: createAppConfig(),
      agentId: "secondary",
    });
  });

  it("allows per-call get overrides to bypass wiki and force memory fallback", async () => {
    const { rootDir, config } = await createQueryVault({
      initialize: true,
      config: {
        search: { backend: "shared", corpus: "wiki" },
      },
    });
    await fs.writeFile(
      path.join(rootDir, "sources", "MEMORY.md"),
      renderWikiMarkdown({
        frontmatter: { pageType: "source", id: "source.memory.shadow", title: "Shadow Memory" },
        body: "# Shadow Memory\n\nwiki copy\n",
      }),
      "utf8",
    );
    const manager = createMemoryManager({
      readResult: {
        path: "MEMORY.md",
        text: "forced memory read",
      },
    });
    getActiveMemorySearchManagerMock.mockResolvedValue({ manager });

    const result = await getMemoryWikiPage({
      config,
      appConfig: createAppConfig(),
      lookup: "MEMORY.md",
      searchCorpus: "memory",
    });

    expect(result?.corpus).toBe("memory");
    expect(result?.content).toBe("forced memory read");
    expect(manager.readFile).toHaveBeenCalled();
  });
});

¤ Dauer der Verarbeitung: 0.23 Sekunden  (vorverarbeitet am  2026-04-27) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.