Files
openclaw/src/agents/context-window-guard.ts
Ayaan Zaidi e9f70e8585 fix: satisfy lint curly rule (#6310)
* fix: satisfy lint curly rule

* docs: apply oxfmt formatting
2026-02-01 20:04:53 +05:30

75 lines
2.4 KiB
TypeScript

import type { OpenClawConfig } from "../config/config.js";
export const CONTEXT_WINDOW_HARD_MIN_TOKENS = 16_000;
export const CONTEXT_WINDOW_WARN_BELOW_TOKENS = 32_000;
export type ContextWindowSource = "model" | "modelsConfig" | "agentContextTokens" | "default";
export type ContextWindowInfo = {
tokens: number;
source: ContextWindowSource;
};
function normalizePositiveInt(value: unknown): number | null {
if (typeof value !== "number" || !Number.isFinite(value)) {
return null;
}
const int = Math.floor(value);
return int > 0 ? int : null;
}
export function resolveContextWindowInfo(params: {
cfg: OpenClawConfig | undefined;
provider: string;
modelId: string;
modelContextWindow?: number;
defaultTokens: number;
}): ContextWindowInfo {
const fromModelsConfig = (() => {
const providers = params.cfg?.models?.providers as
| Record<string, { models?: Array<{ id?: string; contextWindow?: number }> }>
| undefined;
const providerEntry = providers?.[params.provider];
const models = Array.isArray(providerEntry?.models) ? providerEntry.models : [];
const match = models.find((m) => m?.id === params.modelId);
return normalizePositiveInt(match?.contextWindow);
})();
const fromModel = normalizePositiveInt(params.modelContextWindow);
const baseInfo = fromModelsConfig
? { tokens: fromModelsConfig, source: "modelsConfig" as const }
: fromModel
? { tokens: fromModel, source: "model" as const }
: { tokens: Math.floor(params.defaultTokens), source: "default" as const };
const capTokens = normalizePositiveInt(params.cfg?.agents?.defaults?.contextTokens);
if (capTokens && capTokens < baseInfo.tokens) {
return { tokens: capTokens, source: "agentContextTokens" };
}
return baseInfo;
}
export type ContextWindowGuardResult = ContextWindowInfo & {
shouldWarn: boolean;
shouldBlock: boolean;
};
export function evaluateContextWindowGuard(params: {
info: ContextWindowInfo;
warnBelowTokens?: number;
hardMinTokens?: number;
}): ContextWindowGuardResult {
const warnBelow = Math.max(
1,
Math.floor(params.warnBelowTokens ?? CONTEXT_WINDOW_WARN_BELOW_TOKENS),
);
const hardMin = Math.max(1, Math.floor(params.hardMinTokens ?? CONTEXT_WINDOW_HARD_MIN_TOKENS));
const tokens = Math.max(0, Math.floor(params.info.tokens));
return {
...params.info,
tokens,
shouldWarn: tokens > 0 && tokens < warnBelow,
shouldBlock: tokens > 0 && tokens < hardMin,
};
}