Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions src/components/providers/forms/OpenCodeFormFields.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,53 @@ export function OpenCodeFormFields({
});
};

// Model limit handlers (limit.context and limit.output)
const handleModelLimitContextChange = (modelKey: string, value: string) => {
const model = models[modelKey];
const numValue = value.trim() ? Number(value) : undefined;
if (numValue !== undefined && !Number.isFinite(numValue)) return;
const currentLimit = model.limit || {};
// If both context and output are undefined, remove limit entirely
if (numValue === undefined && currentLimit.output === undefined) {
const { limit: _, ...rest } = model;
Comment on lines +476 to +477
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve other limit keys when clearing context/output

When the user clears context here, the branch deletes the whole limit object as soon as output is undefined, which also drops any existing limit.input (supported in OpenCode model metadata) or future limit fields. This causes silent config data loss for models imported from richer configs; the sibling handleModelLimitOutputChange has the same pattern. Only remove limit after checking that no keys remain after applying the edit.

Useful? React with 👍 / 👎.

onModelsChange({
...models,
[modelKey]: rest as OpenCodeModel,
});
} else {
onModelsChange({
...models,
[modelKey]: {
...model,
limit: { ...currentLimit, context: numValue },
},
});
}
};

const handleModelLimitOutputChange = (modelKey: string, value: string) => {
const model = models[modelKey];
const numValue = value.trim() ? Number(value) : undefined;
if (numValue !== undefined && !Number.isFinite(numValue)) return;
const currentLimit = model.limit || {};
// If both context and output are undefined, remove limit entirely
if (currentLimit.context === undefined && numValue === undefined) {
const { limit: _, ...rest } = model;
onModelsChange({
...models,
[modelKey]: rest as OpenCodeModel,
});
} else {
onModelsChange({
...models,
[modelKey]: {
...model,
limit: { ...currentLimit, output: numValue },
},
});
}
};

// Extra Options handlers
const handleAddExtraOption = () => {
const newKey = `option-${Date.now()}`;
Expand Down Expand Up @@ -827,6 +874,59 @@ export function OpenCodeFormFields({
)}
</div>

{/* Token Limits (model.limit) */}
<div className="space-y-2">
<span className="text-xs font-medium text-muted-foreground">
{t("opencode.tokenLimits", {
defaultValue: "Token Limits",
})}
</span>
<div className="flex items-center gap-2">
<span className="text-xs text-muted-foreground w-24 shrink-0">
{t("opencode.limitContext", {
defaultValue: "Context Window",
})}
</span>
<Input
type="number"
value={model.limit?.context ?? ""}
onChange={(e) =>
handleModelLimitContextChange(key, e.target.value)
}
placeholder={t("opencode.limitContextPlaceholder", {
defaultValue: "e.g. 128000",
})}
className="flex-1"
min={1}
/>
</div>
<div className="flex items-center gap-2">
<span className="text-xs text-muted-foreground w-24 shrink-0">
{t("opencode.limitOutput", {
defaultValue: "Max Output",
})}
</span>
<Input
type="number"
value={model.limit?.output ?? ""}
onChange={(e) =>
handleModelLimitOutputChange(key, e.target.value)
}
placeholder={t("opencode.limitOutputPlaceholder", {
defaultValue: "e.g. 4096",
})}
className="flex-1"
min={1}
/>
</div>
<p className="text-xs text-muted-foreground">
{t("opencode.tokenLimitsHint", {
defaultValue:
"Set context window and max output token limits for this model",
})}
</p>
</div>

{/* SDK Options (model.options) */}
<div className="space-y-2">
<div className="flex items-center justify-between">
Expand Down
8 changes: 7 additions & 1 deletion src/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,13 @@
"modelExtraFieldKeyPlaceholder": "variants",
"sdkOptions": "SDK Options",
"modelOptionKeyPlaceholder": "provider",
"modelOptionValuePlaceholder": "{\"order\": [\"baseten\"]}"
"modelOptionValuePlaceholder": "{\"order\": [\"baseten\"]}",
"tokenLimits": "Token Limits",
"limitContext": "Context Window",
"limitOutput": "Max Output",
"limitContextPlaceholder": "e.g. 128000",
"limitOutputPlaceholder": "e.g. 4096",
"tokenLimitsHint": "Set context window and max output token limits for this model"
},
"providerPreset": {
"label": "Provider Preset",
Expand Down
8 changes: 7 additions & 1 deletion src/i18n/locales/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1028,7 +1028,13 @@
"modelExtraFieldKeyPlaceholder": "variants",
"sdkOptions": "SDK オプション",
"modelOptionKeyPlaceholder": "provider",
"modelOptionValuePlaceholder": "{\"order\": [\"baseten\"]}"
"modelOptionValuePlaceholder": "{\"order\": [\"baseten\"]}",
"tokenLimits": "トークン制限",
"limitContext": "コンテキストウィンドウ",
"limitOutput": "最大出力",
"limitContextPlaceholder": "例: 128000",
"limitOutputPlaceholder": "例: 4096",
"tokenLimitsHint": "このモデルのコンテキストウィンドウと最大出力トークン制限を設定"
},
"providerPreset": {
"label": "プロバイダータイプ",
Expand Down
8 changes: 7 additions & 1 deletion src/i18n/locales/zh.json
Original file line number Diff line number Diff line change
Expand Up @@ -1029,7 +1029,13 @@
"modelExtraFieldKeyPlaceholder": "variants",
"sdkOptions": "SDK 选项",
"modelOptionKeyPlaceholder": "provider",
"modelOptionValuePlaceholder": "{\"order\": [\"baseten\"]}"
"modelOptionValuePlaceholder": "{\"order\": [\"baseten\"]}",
"tokenLimits": "Token 限制",
"limitContext": "上下文窗口",
"limitOutput": "最大输出",
"limitContextPlaceholder": "如 128000",
"limitOutputPlaceholder": "如 4096",
"tokenLimitsHint": "设置此模型的上下文窗口和最大输出 token 限制"
},
"providerPreset": {
"label": "预设供应商",
Expand Down
Loading