fix: unify context limit resolution behind provider API (#11213)

Signed-off-by: Jack Amadeo <jackamadeo@squareup.com>
This commit is contained in:
Jack Amadeo
2026-08-26 14:34:16 +00:00
committed by GitHub
parent 73b9938d73
commit 6357f73ea5
62 changed files with 1547 additions and 679 deletions
@@ -160,6 +160,7 @@ describe('applyGooseSessionNotification', () => {
type: 'tokenState',
tokenState: {
totalTokens: 42,
contextLimit: 200,
accumulatedInputTokens: 10,
accumulatedOutputTokens: 15,
accumulatedTotalTokens: 25,
@@ -219,7 +219,7 @@ describe('ACP providers', () => {
expect(result.connectionChecked).toBe(true);
expect(result.provider.metadata.known_models).toEqual([
{ name: 'claude-sonnet', context_limit: 0, reasoning: undefined },
{ name: 'claude-sonnet', context_limit: undefined, reasoning: undefined },
]);
});
@@ -268,7 +268,7 @@ describe('ACP providers', () => {
});
expect(enabled.is_configured).toBe(true);
expect(enabled.metadata.known_models).toEqual([
{ name: 'claude-sonnet', context_limit: 0, reasoning: undefined },
{ name: 'claude-sonnet', context_limit: undefined, reasoning: undefined },
]);
});
@@ -872,6 +872,7 @@ describe('createAcpSessionNotificationAdapter', () => {
type: 'tokenState',
tokenState: {
totalTokens: 42,
contextLimit: 200,
accumulatedInputTokens: 10,
accumulatedOutputTokens: 15,
accumulatedTotalTokens: 25,
@@ -15,6 +15,7 @@ export function applyGooseSessionNotification(
type: 'tokenState',
tokenState: {
totalTokens: update.used,
contextLimit: update.contextLimit,
accumulatedInputTokens: update.accumulatedInputTokens,
accumulatedOutputTokens: update.accumulatedOutputTokens,
accumulatedTotalTokens: update.accumulatedInputTokens + update.accumulatedOutputTokens,
+1 -1
View File
@@ -71,7 +71,7 @@ function providerEntryToDetails(entry: ProviderInventoryEntryDto): ProviderDetai
})),
known_models: entry.models.map((model) => ({
name: model.id,
context_limit: model.contextLimit ?? 0,
context_limit: model.contextLimit ?? undefined,
reasoning: model.reasoning ?? undefined,
})),
setup_steps: entry.setupSteps,
+1
View File
@@ -522,6 +522,7 @@ export default function BaseChat({
initialValue={initialPrompt}
setView={setView}
totalTokens={tokenState?.totalTokens ?? session?.usage?.total_tokens ?? undefined}
contextLimit={tokenState?.contextLimit}
accumulatedInputTokens={
tokenState?.accumulatedInputTokens ??
session?.accumulated_usage?.input_tokens ??
+22 -3
View File
@@ -82,7 +82,7 @@ const removeQueuedMessage = (messages: QueuedMessage[], messageId: string): Queu
const MAX_IMAGES_PER_MESSAGE = 10;
const TOKEN_LIMIT_DEFAULT = 128000; // fallback for custom models that the backend doesn't know about
const TOKEN_LIMIT_DEFAULT = 128000; // used before a session has a backend-resolved limit
const getContextAlertType = (totalTokens: number, tokenLimit: number): AlertType => {
const percentage = tokenLimit ? (totalTokens / tokenLimit) * 100 : 0;
@@ -172,6 +172,7 @@ interface ChatInputProps {
onFilesProcessed?: () => void;
setView: (view: View) => void;
totalTokens?: number;
contextLimit?: number;
accumulatedInputTokens?: number;
accumulatedOutputTokens?: number;
accumulatedCost?: number | null;
@@ -207,6 +208,7 @@ export default function ChatInput({
onFilesProcessed,
setView,
totalTokens,
contextLimit,
accumulatedInputTokens,
accumulatedOutputTokens,
accumulatedCost,
@@ -581,7 +583,11 @@ export default function ChatInput({
// Load providers and get current model's token limit
const loadProviderDetails = async () => {
try {
// Reset token limit loaded state
if (sessionId) {
setTokenLimit(0);
setIsTokenLimitLoaded(false);
return;
}
setIsTokenLimitLoaded(false);
// Use effective model/provider (includes overrides from in-session model changes),
@@ -642,7 +648,20 @@ export default function ChatInput({
useEffect(() => {
loadProviderDetails();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [effectiveModel, effectiveProvider, configModel, configProvider]);
}, [effectiveModel, effectiveProvider, configModel, configProvider, sessionId]);
useEffect(() => {
if (contextLimit === undefined) {
if (sessionId) {
setTokenLimit(0);
setIsTokenLimitLoaded(false);
}
return;
}
setTokenLimit(contextLimit);
setIsTokenLimitLoaded(true);
}, [contextLimit, sessionId]);
// Handle token usage alerts
useEffect(() => {
@@ -459,8 +459,8 @@ export default function CustomProviderForm({
const modelList = models
.split(',')
.map((m) => m.trim())
.filter((m) => m);
.map((name) => name.trim())
.filter(Boolean);
let allHeaders = [...headers];
+1
View File
@@ -13,6 +13,7 @@ export type TokenState = {
inputTokens: number;
outputTokens: number;
totalTokens: number;
contextLimit?: number;
};
export interface ChatType {
+1 -1
View File
@@ -13,7 +13,7 @@ export type ConfigKey = {
};
export type ModelInfo = {
context_limit: number;
context_limit?: number | null;
currency?: string | null;
input_token_cost?: number | null;
name: string;