mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 05:30:42 +00:00
fix: align tool-result guard budget
This commit is contained in:
@@ -11,6 +11,7 @@ Docs: https://docs.openclaw.ai
|
||||
|
||||
### Fixes
|
||||
|
||||
- Agents/tool-result guard: use the resolved runtime context token budget for non-context-engine tool-result overflow checks, so long tool-heavy sessions no longer compact early when `contextTokens` is larger than native `contextWindow`. Fixes #74917. Thanks @kAIborg24.
|
||||
- Gateway/systemd: exit with sysexits 78 for supervised lock and `EADDRINUSE` conflicts so `RestartPreventExitStatus=78` stops `Restart=always` restart loops instead of repeatedly reloading plugins against an occupied port. Fixes #75115. Thanks @yhyatt.
|
||||
- Plugins/runtime-deps: replace stale symlinked mirror target roots before writing runtime-mirror temp files and skip rewriting already materialized hardlinks, so cross-version container upgrades no longer crash-loop on read-only image-layer paths while warm mirrors do less churn. Fixes #75108; refs #75069. Thanks @coletebou and @xiaohuaxi.
|
||||
- Auto-reply/group chats: fall back to automatic source delivery when a channel precomputes message-tool-only replies but the `message` tool is unavailable, so Discord/Slack-style group turns do not silently complete without a visible reply. Fixes #74868. Thanks @kagura-agent.
|
||||
|
||||
@@ -869,3 +869,43 @@ describe("runEmbeddedAttempt context engine mid-turn precheck integration", () =
|
||||
expect(result.messagesSnapshot).toEqual([seedMessage]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("runEmbeddedAttempt tool-result guard budget wiring", () => {
|
||||
const sessionKey = "agent:main:guildchat:channel:tool-result-guard-budget";
|
||||
const tempPaths: string[] = [];
|
||||
|
||||
beforeEach(() => {
|
||||
resetEmbeddedAttemptHarness();
|
||||
clearMemoryPluginState();
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await cleanupTempPaths(tempPaths);
|
||||
clearMemoryPluginState();
|
||||
vi.restoreAllMocks();
|
||||
});
|
||||
|
||||
it("uses the resolved contextTokenBudget before model contextWindow", async () => {
|
||||
await createContextEngineAttemptRunner({
|
||||
contextEngine: createContextEngineBootstrapAndAssemble(),
|
||||
sessionKey,
|
||||
tempPaths,
|
||||
attemptOverrides: {
|
||||
contextTokenBudget: 1_000_000,
|
||||
model: {
|
||||
api: "openai-completions",
|
||||
provider: "openai",
|
||||
compat: {},
|
||||
contextWindow: 200_000,
|
||||
input: ["text"],
|
||||
} as never,
|
||||
},
|
||||
});
|
||||
|
||||
expect(hoisted.installToolResultContextGuardMock).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
contextWindowTokens: 1_000_000,
|
||||
}),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1528,7 +1528,12 @@ export async function runEmbeddedAttempt(
|
||||
};
|
||||
const contextTokenBudgetForGuard = Math.max(
|
||||
1,
|
||||
Math.floor(params.contextTokenBudget ?? DEFAULT_CONTEXT_TOKENS),
|
||||
Math.floor(
|
||||
params.contextTokenBudget ??
|
||||
params.model.contextWindow ??
|
||||
params.model.maxTokens ??
|
||||
DEFAULT_CONTEXT_TOKENS,
|
||||
),
|
||||
);
|
||||
const toolResultMaxCharsForGuard = resolveLiveToolResultMaxChars({
|
||||
contextWindowTokens: contextTokenBudgetForGuard,
|
||||
@@ -1544,12 +1549,7 @@ export async function runEmbeddedAttempt(
|
||||
if (!activeContextEngine || activeContextEngine.info.ownsCompaction !== true) {
|
||||
removeToolResultContextGuard = installToolResultContextGuard({
|
||||
agent: activeSession.agent,
|
||||
contextWindowTokens: Math.max(
|
||||
1,
|
||||
Math.floor(
|
||||
params.model.contextWindow ?? params.model.maxTokens ?? DEFAULT_CONTEXT_TOKENS,
|
||||
),
|
||||
),
|
||||
contextWindowTokens: contextTokenBudgetForGuard,
|
||||
...(midTurnPrecheckEnabled
|
||||
? {
|
||||
midTurnPrecheck: {
|
||||
|
||||
Reference in New Issue
Block a user