mirror of
http://192.168.0.88:13333/lywsvip/openclaw-zero-token.git
synced 2026-05-08 08:08:33 +08:00
Major upgrade from e26988a38 to upstream v2026.3.28 (f9b107928).
Key changes:
- Upstream src/, ui/, extensions/ (89 bundled extensions)
- Zero-token web providers preserved in src/zero-token/
- AskOnce plugin restored and registered as CLI command
- Added missing packages: @anthropic-ai/vertex-sdk, @modelcontextprotocol/sdk
- Fixed tsconfig rootDir, skipLibCheck for plugin-sdk DTS build
- Added askonce to bundled plugin metadata and package.json exports
- Fixed AskOnce CLI command registration (missing commands metadata)
- Restored AskOnce adapter imports (correct 5-level relative paths)
- Removed stale migration artifacts from root directory
170 lines
3.9 KiB
TypeScript
170 lines
3.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import {
|
|
applyQueueRuntimeSettings,
|
|
buildQueueSummaryPrompt,
|
|
clearQueueSummaryState,
|
|
drainCollectItemIfNeeded,
|
|
previewQueueSummaryPrompt,
|
|
} from "./queue-helpers.js";
|
|
|
|
describe("applyQueueRuntimeSettings", () => {
|
|
it("updates runtime queue settings with normalization", () => {
|
|
const target = {
|
|
mode: "followup" as const,
|
|
debounceMs: 1000,
|
|
cap: 20,
|
|
dropPolicy: "summarize" as const,
|
|
};
|
|
|
|
applyQueueRuntimeSettings({
|
|
target,
|
|
settings: {
|
|
mode: "collect",
|
|
debounceMs: -12,
|
|
cap: 9.8,
|
|
dropPolicy: "new",
|
|
},
|
|
});
|
|
|
|
expect(target).toEqual({
|
|
mode: "collect",
|
|
debounceMs: 0,
|
|
cap: 9,
|
|
dropPolicy: "new",
|
|
});
|
|
});
|
|
|
|
it("keeps existing values when optional settings are missing/invalid", () => {
|
|
const target = {
|
|
mode: "followup" as const,
|
|
debounceMs: 1000,
|
|
cap: 20,
|
|
dropPolicy: "summarize" as const,
|
|
};
|
|
|
|
applyQueueRuntimeSettings({
|
|
target,
|
|
settings: {
|
|
mode: "queue",
|
|
cap: 0,
|
|
},
|
|
});
|
|
|
|
expect(target).toEqual({
|
|
mode: "queue",
|
|
debounceMs: 1000,
|
|
cap: 20,
|
|
dropPolicy: "summarize",
|
|
});
|
|
});
|
|
});
|
|
|
|
describe("queue summary helpers", () => {
|
|
it("previewQueueSummaryPrompt does not mutate state", () => {
|
|
const state = {
|
|
dropPolicy: "summarize" as const,
|
|
droppedCount: 2,
|
|
summaryLines: ["first", "second"],
|
|
};
|
|
|
|
const prompt = previewQueueSummaryPrompt({
|
|
state,
|
|
noun: "message",
|
|
});
|
|
|
|
expect(prompt).toContain("[Queue overflow] Dropped 2 messages due to cap.");
|
|
expect(prompt).toContain("first");
|
|
expect(state).toEqual({
|
|
dropPolicy: "summarize",
|
|
droppedCount: 2,
|
|
summaryLines: ["first", "second"],
|
|
});
|
|
});
|
|
|
|
it("buildQueueSummaryPrompt clears state after rendering", () => {
|
|
const state = {
|
|
dropPolicy: "summarize" as const,
|
|
droppedCount: 1,
|
|
summaryLines: ["line"],
|
|
};
|
|
|
|
const prompt = buildQueueSummaryPrompt({
|
|
state,
|
|
noun: "announce",
|
|
});
|
|
|
|
expect(prompt).toContain("[Queue overflow] Dropped 1 announce due to cap.");
|
|
expect(state).toEqual({
|
|
dropPolicy: "summarize",
|
|
droppedCount: 0,
|
|
summaryLines: [],
|
|
});
|
|
});
|
|
|
|
it("clearQueueSummaryState resets summary counters", () => {
|
|
const state = {
|
|
dropPolicy: "summarize" as const,
|
|
droppedCount: 5,
|
|
summaryLines: ["a", "b"],
|
|
};
|
|
clearQueueSummaryState(state);
|
|
expect(state.droppedCount).toBe(0);
|
|
expect(state.summaryLines).toEqual([]);
|
|
});
|
|
});
|
|
|
|
describe("drainCollectItemIfNeeded", () => {
|
|
it("skips when neither force mode nor cross-channel routing is active", async () => {
|
|
const seen: number[] = [];
|
|
const items = [1];
|
|
|
|
const result = await drainCollectItemIfNeeded({
|
|
forceIndividualCollect: false,
|
|
isCrossChannel: false,
|
|
items,
|
|
run: async (item) => {
|
|
seen.push(item);
|
|
},
|
|
});
|
|
|
|
expect(result).toBe("skipped");
|
|
expect(seen).toEqual([]);
|
|
expect(items).toEqual([1]);
|
|
});
|
|
|
|
it("drains one item in force mode", async () => {
|
|
const seen: number[] = [];
|
|
const items = [1, 2];
|
|
|
|
const result = await drainCollectItemIfNeeded({
|
|
forceIndividualCollect: true,
|
|
isCrossChannel: false,
|
|
items,
|
|
run: async (item) => {
|
|
seen.push(item);
|
|
},
|
|
});
|
|
|
|
expect(result).toBe("drained");
|
|
expect(seen).toEqual([1]);
|
|
expect(items).toEqual([2]);
|
|
});
|
|
|
|
it("switches to force mode and returns empty when cross-channel with no queued item", async () => {
|
|
let forced = false;
|
|
|
|
const result = await drainCollectItemIfNeeded({
|
|
forceIndividualCollect: false,
|
|
isCrossChannel: true,
|
|
setForceIndividualCollect: (next) => {
|
|
forced = next;
|
|
},
|
|
items: [],
|
|
run: async () => {},
|
|
});
|
|
|
|
expect(result).toBe("empty");
|
|
expect(forced).toBe(true);
|
|
});
|
|
});
|