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

Quelle  bootstrap-budget.test.ts

  Sprache: JAVA
 

import { describe, expect, it } from "vitest";
import {
  appendBootstrapPromptWarning,
  analyzeBootstrapBudget,
  buildBootstrapInjectionStats,
  buildBootstrapPromptWarning,
  buildBootstrapTruncationReportMeta,
  buildBootstrapTruncationSignature,
  formatBootstrapTruncationWarningLines,
  resolveBootstrapWarningSignaturesSeen,
} from "./bootstrap-budget.js";
import { buildAgentSystemPrompt } from "./system-prompt.js";
import type { WorkspaceBootstrapFile } from "./workspace.js";

describe("buildBootstrapInjectionStats", () => {
  it("maps raw and injected sizes and marks truncation", () => {
    const bootstrapFiles: WorkspaceBootstrapFile[] = [
      {
        name: "AGENTS.md",
        path: "/tmp/AGENTS.md",
        content: "a".repeat(100),
        missing: false,
      },
      {
        name: "SOUL.md",
        path: "/tmp/SOUL.md",
        content: "b".repeat(50),
        missing: false,
      },
    ];
    const injectedFiles = [
      { path: "/tmp/AGENTS.md", content: "a".repeat(100) },
      { path: "/tmp/SOUL.md", content: "b".repeat(20) },
    ];
    const stats = buildBootstrapInjectionStats({
      bootstrapFiles,
      injectedFiles,
    });
    expect(stats).toHaveLength(2);
    expect(stats[0]).toMatchObject({
      name: "AGENTS.md",
      rawChars: 100,
      injectedChars: 100,
      truncated: false,
    });
    expect(stats[1]).toMatchObject({
      name: "SOUL.md",
      rawChars: 50,
      injectedChars: 20,
      truncated: true,
    });
  });
});

describe("analyzeBootstrapBudget", () => {
  it("reports per-file and total-limit causes", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 120,
          truncated: true,
        },
        {
          name: "SOUL.md",
          path: "/tmp/SOUL.md",
          missing: false,
          rawChars: 90,
          injectedChars: 80,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    expect(analysis.hasTruncation).toBe(true);
    expect(analysis.totalNearLimit).toBe(true);
    expect(analysis.truncatedFiles).toHaveLength(2);
    const agents = analysis.truncatedFiles.find((file) => file.name === "AGENTS.md");
    const soul = analysis.truncatedFiles.find((file) => file.name === "SOUL.md");
    expect(agents?.causes).toContain("per-file-limit");
    expect(agents?.causes).toContain("total-limit");
    expect(soul?.causes).toContain("total-limit");
  });

  it("does not force a total-limit cause when totals are within limits", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/AGENTS.md",
          missing: false,
          rawChars: 90,
          injectedChars: 40,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    expect(analysis.truncatedFiles[0]?.causes).toEqual([]);
  });
});

describe("bootstrap prompt warnings", () => {
  it("appends warning details to the turn prompt instead of mutating the system prompt", () => {
    const prompt = appendBootstrapPromptWarning("Please continue.", [
      "AGENTS.md: 200 raw -> 0 injected",
    ]);
    expect(prompt.startsWith("Please continue.")).toBe(true);
    expect(prompt).toContain("[Bootstrap truncation warning]");
    expect(prompt).toContain("Treat Project Context as partial");
    expect(prompt).toContain("- AGENTS.md: 200 raw -> 0 injected");
    expect(prompt.endsWith("- AGENTS.md: 200 raw -> 0 injected")).toBe(true);
  });

  it("preserves raw prompt whitespace when appending warning details", () => {
    const prompt = appendBootstrapPromptWarning("  indented\nkeep tail  ", [
      "AGENTS.md: 200 raw -> 0 injected",
    ]);

    expect(prompt).toContain("  indented\nkeep tail  ");
    expect(prompt.indexOf("  indented\nkeep tail  ")).toBe(0);
  });

  it("preserves exact heartbeat prompts without warning suffixes", () => {
    const heartbeatPrompt = "Read HEARTBEAT.md. Reply HEARTBEAT_OK.";

    expect(
      appendBootstrapPromptWarning(heartbeatPrompt, ["AGENTS.md: 200 raw -> 0 injected"], {
        preserveExactPrompt: heartbeatPrompt,
      }),
    ).toBe(heartbeatPrompt);
  });

  it("resolves seen signatures from report history or legacy single signature", () => {
    expect(
      resolveBootstrapWarningSignaturesSeen({
        bootstrapTruncation: {
          warningSignaturesSeen: ["sig-a"" ""sig-b""sig-a"],
          promptWarningSignature: "legacy-ignored",
        },
      }),
    ).toEqual(["sig-a""sig-b"]);

    expect(
      resolveBootstrapWarningSignaturesSeen({
        bootstrapTruncation: {
          promptWarningSignature: "legacy-only",
        },
      }),
    ).toEqual(["legacy-only"]);

    expect(resolveBootstrapWarningSignaturesSeen(undefined)).toEqual([]);
  });

  it("ignores single-signature fallback when warning mode is off", () => {
    expect(
      resolveBootstrapWarningSignaturesSeen({
        bootstrapTruncation: {
          warningMode: "off",
          promptWarningSignature: "off-mode-signature",
        },
      }),
    ).toEqual([]);

    expect(
      resolveBootstrapWarningSignaturesSeen({
        bootstrapTruncation: {
          warningMode: "off",
          warningSignaturesSeen: ["prior-once-signature"],
          promptWarningSignature: "off-mode-signature",
        },
      }),
    ).toEqual(["prior-once-signature"]);
  });

  it("dedupes warnings in once mode by signature", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    const first = buildBootstrapPromptWarning({
      analysis,
      mode: "once",
    });
    expect(first.warningShown).toBe(true);
    expect(first.signature).toBeTruthy();
    expect(first.lines.join("\n")).toContain("AGENTS.md");

    const second = buildBootstrapPromptWarning({
      analysis,
      mode: "once",
      seenSignatures: first.warningSignaturesSeen,
    });
    expect(second.warningShown).toBe(false);
    expect(second.lines).toEqual([]);
  });

  it("dedupes once mode across non-consecutive repeated signatures", () => {
    const analysisA = analyzeBootstrapBudget({
      files: [
        {
          name: "A.md",
          path: "/tmp/A.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    const analysisB = analyzeBootstrapBudget({
      files: [
        {
          name: "B.md",
          path: "/tmp/B.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    const firstA = buildBootstrapPromptWarning({
      analysis: analysisA,
      mode: "once",
    });
    expect(firstA.warningShown).toBe(true);
    const firstB = buildBootstrapPromptWarning({
      analysis: analysisB,
      mode: "once",
      seenSignatures: firstA.warningSignaturesSeen,
    });
    expect(firstB.warningShown).toBe(true);
    const secondA = buildBootstrapPromptWarning({
      analysis: analysisA,
      mode: "once",
      seenSignatures: firstB.warningSignaturesSeen,
    });
    expect(secondA.warningShown).toBe(false);
  });

  it("includes overflow line when more files are truncated than shown", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "A.md",
          path: "/tmp/A.md",
          missing: false,
          rawChars: 10,
          injectedChars: 1,
          truncated: true,
        },
        {
          name: "B.md",
          path: "/tmp/B.md",
          missing: false,
          rawChars: 10,
          injectedChars: 1,
          truncated: true,
        },
        {
          name: "C.md",
          path: "/tmp/C.md",
          missing: false,
          rawChars: 10,
          injectedChars: 1,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 20,
      bootstrapTotalMaxChars: 10,
    });
    const lines = formatBootstrapTruncationWarningLines({
      analysis,
      maxFiles: 2,
    });
    expect(lines).toContain("+1 more truncated file(s).");
  });

  it("disambiguates duplicate file names in warning lines", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/a/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
        {
          name: "AGENTS.md",
          path: "/tmp/b/AGENTS.md",
          missing: false,
          rawChars: 140,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 300,
    });
    const lines = formatBootstrapTruncationWarningLines({
      analysis,
    });
    expect(lines.join("\n")).toContain("AGENTS.md (/tmp/a/AGENTS.md)");
    expect(lines.join("\n")).toContain("AGENTS.md (/tmp/b/AGENTS.md)");
  });

  it("respects off/always warning modes", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    const signature = buildBootstrapTruncationSignature(analysis);
    const off = buildBootstrapPromptWarning({
      analysis,
      mode: "off",
      seenSignatures: [signature ?? ""],
      previousSignature: signature,
    });
    expect(off.warningShown).toBe(false);
    expect(off.lines).toEqual([]);

    const always = buildBootstrapPromptWarning({
      analysis,
      mode: "always",
      seenSignatures: [signature ?? ""],
      previousSignature: signature,
    });
    expect(always.warningShown).toBe(true);
    expect(always.lines.length).toBeGreaterThan(0);
  });

  it("uses file path in signature to avoid collisions for duplicate names", () => {
    const left = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/a/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    const right = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/b/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    expect(buildBootstrapTruncationSignature(left)).not.toBe(
      buildBootstrapTruncationSignature(right),
    );
  });

  it("builds truncation report metadata from analysis + warning decision", () => {
    const analysis = analyzeBootstrapBudget({
      files: [
        {
          name: "AGENTS.md",
          path: "/tmp/AGENTS.md",
          missing: false,
          rawChars: 150,
          injectedChars: 100,
          truncated: true,
        },
      ],
      bootstrapMaxChars: 120,
      bootstrapTotalMaxChars: 200,
    });
    const warning = buildBootstrapPromptWarning({
      analysis,
      mode: "once",
    });
    const meta = buildBootstrapTruncationReportMeta({
      analysis,
      warningMode: "once",
      warning,
    });
    expect(meta.warningMode).toBe("once");
    expect(meta.warningShown).toBe(true);
    expect(meta.truncatedFiles).toBe(1);
    expect(meta.nearLimitFiles).toBeGreaterThanOrEqual(1);
    expect(meta.promptWarningSignature).toBeTruthy();
    expect(meta.warningSignaturesSeen?.length).toBeGreaterThan(0);
  });

  it("improves cache-relevant system prompt stability versus legacy warning injection", () => {
    const contextFiles = [{ path: "AGENTS.md", content: "Follow AGENTS guidance." }];
    const warningLines = ["AGENTS.md: 200 raw -> 0 injected"];
    const stableSystemPrompt = buildAgentSystemPrompt({
      workspaceDir: "/tmp/openclaw",
      contextFiles,
    });
    const optimizedTurns = [stableSystemPrompt, stableSystemPrompt, stableSystemPrompt];
    const injectLegacyWarning = (prompt: string, lines: string[]) => {
      const warningBlock = [
        "⚠ Bootstrap truncation warning:",
        ...lines.map((line) => `- ${line}`),
        "",
      ].join("\n");
      return prompt.replace("## AGENTS.md", `${warningBlock}## AGENTS.md`);
    };
    const legacyTurns = [
      injectLegacyWarning(optimizedTurns[0] ?? "", warningLines),
      optimizedTurns[1] ?? "",
      injectLegacyWarning(optimizedTurns[2] ?? "", warningLines),
    ];
    const cacheHitRate = (turns: string[]) => {
      const hits = turns.slice(1).filter((turn, index) => turn === turns[index]).length;
      return hits / Math.max(1, turns.length - 1);
    };

    expect(cacheHitRate(legacyTurns)).toBe(0);
    expect(cacheHitRate(optimizedTurns)).toBe(1);
    expect(optimizedTurns[0]).not.toContain("⚠ Bootstrap truncation warning:");
  });
});

Messung V0.5 in Prozent
C=98 H=96 G=96

¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet am  2026-05-26) ¤

*© 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.