mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 06:00:43 +00:00
Tests: restore context-engine usage proof
This commit is contained in:
@@ -14,6 +14,7 @@ import { resolveHeartbeatPromptForSystemPrompt } from "../../heartbeat-system-pr
|
||||
import { buildActiveMusicGenerationTaskPromptContextForSession } from "../../music-generation-task-status.js";
|
||||
import { prependSystemPromptAdditionAfterCacheBoundary } from "../../system-prompt-cache-boundary.js";
|
||||
import { resolveEffectiveToolFsWorkspaceOnly } from "../../tool-fs-policy.js";
|
||||
import { derivePromptTokens, type NormalizedUsage } from "../../usage.js";
|
||||
import { buildActiveVideoGenerationTaskPromptContextForSession } from "../../video-generation-task-status.js";
|
||||
import { buildEmbeddedCompactionRuntimeContext } from "../compaction-runtime-context.js";
|
||||
import { log } from "../logger.js";
|
||||
@@ -255,15 +256,26 @@ export function buildAfterTurnRuntimeContext(params: {
|
||||
ownerNumbers: params.attempt.ownerNumbers,
|
||||
}),
|
||||
...(typeof params.tokenBudget === "number" &&
|
||||
Number.isFinite(params.tokenBudget) &&
|
||||
params.tokenBudget > 0
|
||||
Number.isFinite(params.tokenBudget) &&
|
||||
params.tokenBudget > 0
|
||||
? { tokenBudget: Math.floor(params.tokenBudget) }
|
||||
: {}),
|
||||
...(typeof params.currentTokenCount === "number" &&
|
||||
Number.isFinite(params.currentTokenCount) &&
|
||||
params.currentTokenCount > 0
|
||||
Number.isFinite(params.currentTokenCount) &&
|
||||
params.currentTokenCount > 0
|
||||
? { currentTokenCount: Math.floor(params.currentTokenCount) }
|
||||
: {}),
|
||||
...(params.promptCache ? { promptCache: params.promptCache } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildAfterTurnRuntimeContextFromUsage(
|
||||
params: Omit<Parameters<typeof buildAfterTurnRuntimeContext>[0], "currentTokenCount"> & {
|
||||
lastCallUsage?: NormalizedUsage;
|
||||
},
|
||||
): ContextEngineRuntimeContext {
|
||||
return buildAfterTurnRuntimeContext({
|
||||
...params,
|
||||
currentTokenCount: derivePromptTokens(params.lastCallUsage),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import { buildAgentSystemPrompt } from "../../system-prompt.js";
|
||||
import {
|
||||
buildContextEnginePromptCacheInfo,
|
||||
buildAfterTurnRuntimeContext,
|
||||
buildAfterTurnRuntimeContextFromUsage,
|
||||
composeSystemPromptWithHookContext,
|
||||
decodeHtmlEntitiesInObject,
|
||||
mergeOrphanedTrailingUserPrompt,
|
||||
@@ -2881,6 +2882,49 @@ describe("buildAfterTurnRuntimeContext", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("derives afterTurn token count from the current assistant usage snapshot", () => {
|
||||
const lastCallUsage = {
|
||||
input: 10,
|
||||
output: 5,
|
||||
cacheRead: 40,
|
||||
cacheWrite: 2,
|
||||
total: 57,
|
||||
};
|
||||
const promptCache = buildContextEnginePromptCacheInfo({ lastCallUsage });
|
||||
const legacy = buildAfterTurnRuntimeContextFromUsage({
|
||||
attempt: {
|
||||
sessionKey: "agent:main:session:abc",
|
||||
messageChannel: "slack",
|
||||
messageProvider: "slack",
|
||||
agentAccountId: "acct-1",
|
||||
authProfileId: "openai:p1",
|
||||
config: { plugins: { slots: { contextEngine: "lossless-claw" } } } as OpenClawConfig,
|
||||
skillsSnapshot: undefined,
|
||||
senderIsOwner: true,
|
||||
provider: "openai-codex",
|
||||
modelId: "gpt-5.4",
|
||||
thinkLevel: "off",
|
||||
reasoningLevel: "on",
|
||||
extraSystemPrompt: "extra",
|
||||
ownerNumbers: ["+15555550123"],
|
||||
},
|
||||
workspaceDir: "/tmp/workspace",
|
||||
agentDir: "/tmp/agent",
|
||||
tokenBudget: 1050000,
|
||||
lastCallUsage,
|
||||
promptCache,
|
||||
});
|
||||
|
||||
expect(legacy).toMatchObject({
|
||||
currentTokenCount: 52,
|
||||
promptCache: {
|
||||
lastCallUsage: {
|
||||
total: 57,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it("preserves sender and channel routing context for scoped compaction discovery", () => {
|
||||
const legacy = buildAfterTurnRuntimeContext({
|
||||
attempt: {
|
||||
|
||||
@@ -120,7 +120,7 @@ import {
|
||||
resolveTranscriptPolicy,
|
||||
shouldAllowProviderOwnedThinkingReplay,
|
||||
} from "../../transcript-policy.js";
|
||||
import { derivePromptTokens, normalizeUsage, type NormalizedUsage } from "../../usage.js";
|
||||
import { normalizeUsage, type NormalizedUsage } from "../../usage.js";
|
||||
import { DEFAULT_BOOTSTRAP_FILENAME } from "../../workspace.js";
|
||||
import { isRunnerAbortError } from "../abort.js";
|
||||
import { isCacheTtlEligibleProvider, readLastCacheTtlTimestamp } from "../cache-ttl.js";
|
||||
@@ -193,6 +193,7 @@ import {
|
||||
} from "./attempt.context-engine-helpers.js";
|
||||
import {
|
||||
buildAfterTurnRuntimeContext,
|
||||
buildAfterTurnRuntimeContextFromUsage,
|
||||
mergeOrphanedTrailingUserPrompt,
|
||||
prependSystemPromptAddition,
|
||||
resolveAttemptFsWorkspaceOnly,
|
||||
@@ -256,6 +257,7 @@ export {
|
||||
} from "./attempt.thread-helpers.js";
|
||||
export {
|
||||
buildAfterTurnRuntimeContext,
|
||||
buildAfterTurnRuntimeContextFromUsage,
|
||||
mergeOrphanedTrailingUserPrompt,
|
||||
prependSystemPromptAddition,
|
||||
resolveAttemptFsWorkspaceOnly,
|
||||
@@ -2296,13 +2298,12 @@ export async function runEmbeddedAttempt(
|
||||
|
||||
// Let the active context engine run its post-turn lifecycle.
|
||||
if (params.contextEngine) {
|
||||
const runtimeCurrentTokenCount = derivePromptTokens(lastCallUsage);
|
||||
const afterTurnRuntimeContext = buildAfterTurnRuntimeContext({
|
||||
const afterTurnRuntimeContext = buildAfterTurnRuntimeContextFromUsage({
|
||||
attempt: params,
|
||||
workspaceDir: effectiveWorkspace,
|
||||
agentDir,
|
||||
tokenBudget: params.contextTokenBudget,
|
||||
currentTokenCount: runtimeCurrentTokenCount,
|
||||
lastCallUsage,
|
||||
promptCache,
|
||||
});
|
||||
await finalizeAttemptContextEngineTurn({
|
||||
|
||||
Reference in New Issue
Block a user