diff --git a/package-lock.json b/package-lock.json index 5c62f29f..100833b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2809,9 +2809,9 @@ } }, "node_modules/@opencode-ai/sdk": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.1.11.tgz", - "integrity": "sha512-vqdNDz8Q+4bygmDdQem6oxhU31ci4JVdoND4ZJNeCs9x6OIU6MM3ybgemGpzNkgtJDlfb4xCdrPaZZ6Sr3V1IQ==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@opencode-ai/sdk/-/sdk-1.2.6.tgz", + "integrity": "sha512-dWMF8Aku4h7fh8sw5tQ2FtbqRLbIFT8FcsukpxTird49ax7oUXP+gzqxM/VdxHjfksQvzLBjLZyMdDStc5g7xA==", "license": "MIT" }, "node_modules/@pinojs/redact": { @@ -12075,7 +12075,7 @@ "dependencies": { "@git-diff-view/solid": "^0.0.8", "@kobalte/core": "0.13.11", - "@opencode-ai/sdk": "1.1.11", + "@opencode-ai/sdk": "1.2.6", "@solidjs/router": "^0.13.0", "@suid/icons-material": "^0.9.0", "@suid/material": "^0.19.0", diff --git a/packages/ui/package.json b/packages/ui/package.json index 7a75280f..e619fff6 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -13,7 +13,7 @@ "dependencies": { "@git-diff-view/solid": "^0.0.8", "@kobalte/core": "0.13.11", - "@opencode-ai/sdk": "1.1.11", + "@opencode-ai/sdk": "1.2.6", "@solidjs/router": "^0.13.0", "@suid/icons-material": "^0.9.0", "@suid/material": "^0.19.0", diff --git a/packages/ui/src/stores/message-v2/session-info.ts b/packages/ui/src/stores/message-v2/session-info.ts index dd0fe16f..a0970ebf 100644 --- a/packages/ui/src/stores/message-v2/session-info.ts +++ b/packages/ui/src/stores/message-v2/session-info.ts @@ -63,9 +63,14 @@ export function updateSessionInfo(instanceId: string, sessionId: string): void { resolveSelectedModel(instanceProviders, latestProviderId, latestModelId) let modelOutputLimit = DEFAULT_MODEL_OUTPUT_LIMIT + let modelInputLimit: number | null = null if (selectedModel) { contextWindow = selectedModel.limit?.context ?? 0 + const inputLimit = selectedModel.limit?.input + if (typeof inputLimit === "number" && inputLimit > 0) { + modelInputLimit = inputLimit + } const outputLimit = selectedModel.limit?.output if (typeof outputLimit === "number" && outputLimit > 0) { modelOutputLimit = Math.min(outputLimit, DEFAULT_MODEL_OUTPUT_LIMIT) @@ -107,7 +112,13 @@ export function updateSessionInfo(instanceId: string, sessionId: string): void { const outputBudget = Math.min(modelOutputLimit, DEFAULT_MODEL_OUTPUT_LIMIT) - if (!contextAvailableFromPrevious) { + if (modelInputLimit !== null) { + // Prefer explicit input limits when provided by the API. + // This is used by the UI "Avail" chip. + contextAvailableTokens = modelInputLimit + } + + if (!contextAvailableFromPrevious && contextAvailableTokens === null) { if (contextWindow > 0) { if (latestHasContextUsage && actualUsageTokens > 0) { contextAvailableTokens = Math.max(contextWindow - (actualUsageTokens + outputBudget), 0) diff --git a/packages/ui/src/stores/session-api.ts b/packages/ui/src/stores/session-api.ts index dc8ad63e..9fd12b2c 100644 --- a/packages/ui/src/stores/session-api.ts +++ b/packages/ui/src/stores/session-api.ts @@ -291,12 +291,13 @@ async function createSession(instanceId: string, agent?: string): Promise p.id === session.model.providerId) const initialModel = initialProvider?.models.find((m) => m.id === session.model.modelId) const initialContextWindow = initialModel?.limit?.context ?? 0 + const initialInputLimit = initialModel?.limit?.input ?? 0 const initialSubscriptionModel = initialModel?.cost?.input === 0 && initialModel?.cost?.output === 0 const initialOutputLimit = initialModel?.limit?.output && initialModel.limit.output > 0 ? initialModel.limit.output : DEFAULT_MODEL_OUTPUT_LIMIT - const initialContextAvailable = initialContextWindow > 0 ? initialContextWindow : null + const initialContextAvailable = initialInputLimit > 0 ? initialInputLimit : initialContextWindow > 0 ? initialContextWindow : null setSessionInfoByInstance((prev) => { const next = new Map(prev) @@ -398,10 +399,11 @@ async function forkSession( const forkProvider = instanceProviders.find((p) => p.id === forkedSession.model.providerId) const forkModel = forkProvider?.models.find((m) => m.id === forkedSession.model.modelId) const forkContextWindow = forkModel?.limit?.context ?? 0 + const forkInputLimit = forkModel?.limit?.input ?? 0 const forkSubscriptionModel = forkModel?.cost?.input === 0 && forkModel?.cost?.output === 0 const forkOutputLimit = forkModel?.limit?.output && forkModel.limit.output > 0 ? forkModel.limit.output : DEFAULT_MODEL_OUTPUT_LIMIT - const forkContextAvailable = forkContextWindow > 0 ? forkContextWindow : null + const forkContextAvailable = forkInputLimit > 0 ? forkInputLimit : forkContextWindow > 0 ? forkContextWindow : null setSessionInfoByInstance((prev) => { const next = new Map(prev) diff --git a/packages/ui/src/types/session.ts b/packages/ui/src/types/session.ts index 1cae7c21..d0a864d5 100644 --- a/packages/ui/src/types/session.ts +++ b/packages/ui/src/types/session.ts @@ -90,6 +90,7 @@ export interface Model { variantKeys?: string[] limit?: { context?: number + input?: number output?: number } cost?: {