mirror of
https://github.com/openclaw/openclaw.git
synced 2026-07-17 08:01:38 +00:00
fix(compaction): allow compaction under aws-sdk auth with no static key (#103638)
The compaction safeguard treated a successful keyless auth resolution (ok: true with neither apiKey nor headers) as missing credentials and cancelled compaction. Bedrock providers using auth: "aws-sdk" sign requests with SigV4 at send time and legitimately return no static key or header, so every message on a session large enough to need compaction failed with a false "could not resolve request credentials" error. Trust the registry's ok:true success signal; it already returns ok:false when auth genuinely cannot resolve. Add regression coverage for the keyless SDK-managed auth path. Co-authored-by: Roy Osherove <575051+royosherove@users.noreply.github.com>
This commit is contained in:
@@ -2215,6 +2215,32 @@ describe("compaction-safeguard extension model fallback", () => {
|
||||
expect(retrieved?.model).toEqual(model);
|
||||
});
|
||||
|
||||
it("proceeds with keyless SDK-managed auth (ok:true, no apiKey/headers)", async () => {
|
||||
// Regression: aws-sdk/oauth providers sign requests later and resolve with
|
||||
// neither apiKey nor headers. `ok: true` must be trusted so compaction runs
|
||||
// instead of wedging every message with a false "no credentials" cancel.
|
||||
mockSummarizeInStages.mockReset();
|
||||
mockSummarizeInStages.mockResolvedValue("mock summary");
|
||||
|
||||
const sessionManager = stubSessionManager();
|
||||
const model = createAnthropicModelFixture({ provider: "amazon-bedrock" });
|
||||
setCompactionSafeguardRuntime(sessionManager, { model, recentTurnsPreserve: 0 });
|
||||
|
||||
const getApiKeyAndHeadersMock = vi.fn().mockResolvedValue({ ok: true });
|
||||
const mockContext = createCompactionContext({ sessionManager, getApiKeyAndHeadersMock });
|
||||
const compactionHandler = createCompactionHandler();
|
||||
const event = createCompactionEvent({ messageText: "summarize me", tokensBefore: 1000 });
|
||||
(event.preparation as { settings?: { reserveTokens: number } }).settings = {
|
||||
reserveTokens: 4000,
|
||||
};
|
||||
|
||||
const result = (await compactionHandler(event, mockContext)) as { cancel?: boolean };
|
||||
|
||||
expect(result.cancel).not.toBe(true);
|
||||
expect(getApiKeyAndHeadersMock).toHaveBeenCalledWith(model);
|
||||
expect(mockSummarizeInStages).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("cancels compaction when both ctx.model and runtime.model are undefined", async () => {
|
||||
const sessionManager = stubSessionManager();
|
||||
|
||||
|
||||
@@ -347,15 +347,10 @@ async function resolveModelAuth(
|
||||
reason: `Compaction safeguard could not resolve request credentials for ${model.provider}/${model.id}: ${requestAuth.error}`,
|
||||
};
|
||||
}
|
||||
if (!requestAuth.apiKey && !requestAuth.headers) {
|
||||
log.warn(
|
||||
"Compaction safeguard: no request credentials available; cancelling compaction to preserve history.",
|
||||
);
|
||||
return {
|
||||
ok: false,
|
||||
reason: `Compaction safeguard could not resolve request credentials for ${model.provider}/${model.id}.`,
|
||||
};
|
||||
}
|
||||
// `ok: true` is the registry's authoritative success signal; it already returns
|
||||
// `ok: false` when auth cannot resolve. Do not re-derive failure from absent
|
||||
// key/headers. SDK-managed modes (aws-sdk, oauth) sign the request later and
|
||||
// legitimately carry neither, so gating on them wedges compaction forever.
|
||||
return { ok: true, apiKey: requestAuth.apiKey, headers: requestAuth.headers };
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user