Merge branch 'dev' of github.com:anomalyco/opencode into dev

This commit is contained in:
Frank
2026-07-19 23:30:38 -04:00
28 changed files with 151 additions and 72 deletions
@@ -60,6 +60,8 @@ export function PromptInputV2Composer(props: PromptInputV2ComposerProps) {
controller={props.controller}
borderUnderlay={props.borderUnderlay}
class={props.class}
attachKeybind={command.keybindParts("file.attach")}
attachShortcut={command.keybind("file.attach")}
modelControl={
<PromptInputV2ModelControl
loading={props.controller.model.loading}
@@ -451,12 +453,14 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
options: () => props.controls.agents.options.map((name) => ({ id: name, label: name })),
current: () => props.controls.agents.current,
onSelect: props.controls.agents.select,
keybind: () => command.keybindParts("agent.cycle"),
}
: undefined,
variant: {
options: () => variants().map((value) => ({ id: value, label: value })),
current: () => props.controls.model.selection.variant.current() ?? "default",
onSelect: (value) => props.controls.model.selection.variant.set(value === "default" ? undefined : value),
keybind: () => command.keybindParts("model.variant.cycle"),
},
submit: {
stopping,
+21 -6
View File
@@ -67,7 +67,7 @@ export function useTitlebarRightMount() {
return mount
}
export function Titlebar(props: { update?: TitlebarUpdate }) {
export function Titlebar(props: { update?: TitlebarUpdate; debugTools?: { visible: boolean; toggle: () => void } }) {
const layout = useLayout()
const platform = usePlatform()
const command = useCommand()
@@ -462,7 +462,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
"md:pl-4": !mac(),
}}
>
<ChannelIndicator />
<ChannelIndicator debugTools={props.debugTools} />
<Show when={windows() || linux()}>
<WindowsAppMenu command={command} platform={platform} variant="v2" />
</Show>
@@ -660,9 +660,9 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
</div>
</Show>
<div id="opencode-titlebar-left" class="flex items-center gap-3 min-w-0 px-2" />
<ChannelIndicator />
</div>
</div>
<ChannelIndicator debugTools={props.debugTools} />
</div>
</div>
@@ -747,12 +747,27 @@ function TitlebarUpdateIconButton(props: { state: TitlebarUpdatePillState }) {
)
}
function ChannelIndicator() {
function ChannelIndicator(props: { debugTools?: { visible: boolean; toggle: () => void } }) {
const channel = import.meta.env.VITE_OPENCODE_CHANNEL
if (channel === "dev" && props.debugTools) {
return (
<button
type="button"
class="bg-icon-interactive-base text-[#FFF] font-medium px-2 rounded-sm uppercase font-mono cursor-pointer"
onClick={props.debugTools.toggle}
aria-label="Toggle debug tools"
aria-pressed={props.debugTools.visible}
>
DEV
</button>
)
}
return (
<>
{["beta", "dev"].includes(import.meta.env.VITE_OPENCODE_CHANNEL) && (
{["beta", "dev"].includes(channel) && (
<div class="bg-icon-interactive-base text-[#FFF] font-medium px-2 rounded-sm uppercase font-mono">
{import.meta.env.VITE_OPENCODE_CHANNEL.toUpperCase()}
{channel.toUpperCase()}
</div>
)}
</>
+11 -2
View File
@@ -1,4 +1,5 @@
import { createEffect, Suspense, type ParentProps } from "solid-js"
import { createStore } from "solid-js/store"
import { useNavigate } from "@solidjs/router"
import { DebugBar } from "@/components/debug-bar"
import { TabsInfoPopup } from "@/components/help-button"
@@ -11,6 +12,7 @@ export default function NewLayout(props: ParentProps) {
const platform = usePlatform()
const navigate = useNavigate()
setNavigate(navigate)
const [state, setState] = createStore({ debugTools: true })
createEffect(() => setV2Toast(true))
@@ -32,11 +34,18 @@ export default function NewLayout(props: ParentProps) {
"padding-bottom": "env(safe-area-inset-bottom, 0px)",
}}
>
<Titlebar update={update} />
<Titlebar
update={update}
debugTools={
import.meta.env.DEV
? { visible: state.debugTools, toggle: () => setState("debugTools", (value) => !value) }
: undefined
}
/>
<main class="flex-1 min-h-0 min-w-0 overflow-x-hidden flex flex-col items-start contain-strict">
<Suspense>{props.children}</Suspense>
</main>
{import.meta.env.DEV && <DebugBar inline />}
{import.meta.env.DEV && state.debugTools && <DebugBar inline />}
<TabsInfoPopup />
<ToastRegion v2 />
</div>
+10 -2
View File
@@ -156,6 +156,7 @@ export default function LegacyLayout(props: ParentProps) {
sizing: false,
peek: undefined as string | undefined,
peeked: false,
debugTools: true,
})
const updateVersion = () => {
@@ -2248,7 +2249,14 @@ export default function LegacyLayout(props: ParentProps) {
return (
<div class="relative bg-background-base flex-1 min-h-0 min-w-0 flex flex-col select-none [&_input]:select-text [&_textarea]:select-text [&_[contenteditable]]:select-text">
{autoselecting() ?? ""}
<Titlebar update={titlebarUpdate} />
<Titlebar
update={titlebarUpdate}
debugTools={
import.meta.env.DEV && import.meta.env.VITE_DISABLE_DEBUG_BAR !== "1"
? { visible: state.debugTools, toggle: () => setState("debugTools", (value) => !value) }
: undefined
}
/>
<Show when={updateVersion() !== undefined}>
<UpdateAvailableToast version={updateVersion() ?? ""} install={installUpdate} language={language} />
</Show>
@@ -2393,7 +2401,7 @@ export default function LegacyLayout(props: ParentProps) {
</div>
</div>
</div>
{import.meta.env.DEV && import.meta.env.VITE_DISABLE_DEBUG_BAR !== "1" && <DebugBar />}
{import.meta.env.DEV && import.meta.env.VITE_DISABLE_DEBUG_BAR !== "1" && state.debugTools && <DebugBar />}
</div>
<TabsInfoPopup />
<ToastRegion v2={false} />
+11 -1
View File
@@ -3,13 +3,17 @@ import { LLMError, ProviderErrorEvent } from "./schema"
const patterns = [
/prompt is too long/i,
/request_too_large/i,
/input is too long for requested model/i,
/exceeds the context window/i,
/exceeds (?:the )?(?:model'?s )?maximum context length(?: of [\d,]+ tokens?|\s*\([\d,]+\))/i,
/input token count.*exceeds the maximum/i,
/tokens in request more than max tokens allowed/i,
/maximum prompt length is \d+/i,
/reduce the length of the messages/i,
/maximum context length is \d+ tokens/i,
/exceeds (?:the )?maximum allowed input length of [\d,]+ tokens?/i,
/input \(\d+ tokens\) is longer than the model'?s context length \(\d+ tokens\)/i,
/exceeds the limit of \d+/i,
/exceeds the available context size/i,
/greater than the context length/i,
@@ -21,11 +25,17 @@ const patterns = [
/input length.*exceeds.*context length/i,
/prompt too long; exceeded (?:max )?context length/i,
/too large for model with \d+ maximum context length/i,
/prompt has [\d,]+ tokens?, but the configured context size is [\d,]+ tokens?/i,
/model_context_window_exceeded/i,
/too many tokens/i,
/token limit exceeded/i,
]
const exclusions = [/^(throttling error|service unavailable):/i, /rate limit/i, /too many requests/i]
export const isContextOverflow = (message: string) =>
patterns.some((pattern) => pattern.test(message)) || /^4(00|13)\s*(status code)?\s*\(no body\)/i.test(message)
!exclusions.some((pattern) => pattern.test(message)) &&
(patterns.some((pattern) => pattern.test(message)) || /^4(00|13)\s*(status code)?\s*\(no body\)/i.test(message))
export const isContextOverflowFailure = (failure: unknown) =>
failure instanceof LLMError
+24 -2
View File
@@ -2,7 +2,29 @@ import { describe, expect, test } from "bun:test"
import { isContextOverflow } from "../src"
describe("provider error classification", () => {
test("classifies Z.AI GLM token limit messages as context overflow", () => {
expect(isContextOverflow("tokens in request more than max tokens allowed")).toBe(true)
test("classifies provider token limit messages as context overflow", () => {
const messages = [
"tokens in request more than max tokens allowed",
'{"error":{"type":"request_too_large","message":"Request exceeds the maximum size"}}',
"Requested token count exceeds the model's maximum context length of 131072 tokens.",
"Input length (265330) exceeds model's maximum context length (262144).",
"Input length 131393 exceeds the maximum allowed input length of 131040 tokens.",
"The input (516368 tokens) is longer than the model's context length (262144 tokens).",
"Prompt has 5,958,968 tokens, but the configured context size is 256,000 tokens",
"Too many tokens",
"Token limit exceeded",
]
expect(messages.every(isContextOverflow)).toBe(true)
})
test("does not classify rate limits as context overflow", () => {
const messages = [
"Throttling error: Too many tokens, please wait before trying again.",
"Rate limit exceeded, please retry after 30 seconds.",
"Too many requests. Please slow down.",
]
expect(messages.some(isContextOverflow)).toBe(false)
})
})
+1 -1
View File
@@ -32,7 +32,7 @@ import { ModelStatus } from "./model-status"
import { RuntimeFlags } from "@/effect/runtime-flags"
import { ProviderError } from "./error"
const OPENAI_HEADER_TIMEOUT_DEFAULT = 10_000
const OPENAI_HEADER_TIMEOUT_DEFAULT = 300_000
function wrapSSE(res: Response, ms: number, ctl: AbortController) {
if (typeof ms !== "number" || ms <= 0) return res
@@ -162,7 +162,7 @@ it.live("OpenAI API auth gets default headerTimeout", () =>
Effect.gen(function* () {
const provider = yield* Provider.Service
const openai = yield* provider.getProvider(ProviderV2.ID.openai)
expect(openai.options.headerTimeout).toBe(10_000)
expect(openai.options.headerTimeout).toBe(300_000)
}),
)
}),
@@ -891,7 +891,7 @@
width: 16px;
height: 2px;
border-radius: 999px;
background-color: var(--icon-weak-base);
background-color: var(--v2-icon-icon-muted);
transition: background-color 0.2s ease;
}
@@ -39,6 +39,8 @@ export type PromptInputV2Props = {
borderUnderlay?: boolean
class?: string
modelControl?: JSX.Element
attachKeybind?: string[]
attachShortcut?: string
}
export function PromptInputV2(props: PromptInputV2Props) {
@@ -197,9 +199,9 @@ export function PromptInputV2(props: PromptInputV2Props) {
<PromptInputV2AddMenu
disabled={state.mode === "shell"}
title="Add images and files"
keybind={["Mod", "U"]}
keybind={props.attachKeybind ?? ["Mod", "U"]}
attachLabel="Images and files"
attachShortcut="Mod+U"
attachShortcut={props.attachShortcut ?? "Mod+U"}
commandsLabel="Commands"
contextLabel="Context"
shellLabel="Shell command"
@@ -233,7 +235,11 @@ export function PromptInputV2(props: PromptInputV2Props) {
<Show when={view.variant}>
{(control) => (
<Show when={control().options().length > 1}>
<PromptInputV2ConfiguredSelect title="Choose model variant" control={control()} />
<PromptInputV2ConfiguredSelect
title="Choose model variant"
keybind={["Shift", "Mod", "D"]}
control={control()}
/>
</Show>
)}
</Show>
@@ -512,7 +518,7 @@ function PromptInputV2ConfiguredSelect(props: {
return (
<PromptInputV2Select
title={props.title}
keybind={props.keybind}
keybind={props.control.keybind?.() ?? props.keybind}
options={props.control.options()}
current={current()}
currentIcon={
@@ -536,36 +542,45 @@ export function PromptInputV2Select(props: {
onSelect: (id: string) => void
}) {
return (
<MenuV2 gutter={6} modal={false} placement="top-start" onOpenChange={props.onOpenChange}>
<MenuV2.Trigger
as={ButtonV2}
variant="ghost-muted"
size="normal"
class={`max-w-[220px] justify-start ![font-weight:440] ${props.class ?? ""}`}
title={keybindTitle(props.title, props.keybind)}
>
{props.currentIcon}
<span class="truncate capitalize leading-5">
{props.options.find((option) => option.id === props.current)?.label ?? props.current}
</span>
<span class="-ml-0.5 -mr-1 flex shrink-0">
<IconV2 name="chevron-down" />
</span>
</MenuV2.Trigger>
<MenuV2.Portal>
<MenuV2.Content>
<MenuV2.RadioGroup value={props.current} onChange={props.onSelect}>
<For each={props.options}>
{(option) => (
<MenuV2.RadioItem value={option.id} class="capitalize" closeOnSelect>
{option.label}
</MenuV2.RadioItem>
)}
</For>
</MenuV2.RadioGroup>
</MenuV2.Content>
</MenuV2.Portal>
</MenuV2>
<TooltipV2
placement="top"
value={
<>
{props.title}
<KeybindV2 keys={props.keybind ?? []} variant="neutral" />
</>
}
>
<MenuV2 gutter={6} modal={false} placement="top-start" onOpenChange={props.onOpenChange}>
<MenuV2.Trigger
as={ButtonV2}
variant="ghost-muted"
size="normal"
class={`max-w-[220px] justify-start ![font-weight:440] ${props.class ?? ""}`}
>
{props.currentIcon}
<span class="truncate capitalize leading-5">
{props.options.find((option) => option.id === props.current)?.label ?? props.current}
</span>
<span class="-ml-0.5 -mr-1 flex shrink-0">
<IconV2 name="chevron-down" />
</span>
</MenuV2.Trigger>
<MenuV2.Portal>
<MenuV2.Content>
<MenuV2.RadioGroup value={props.current} onChange={props.onSelect}>
<For each={props.options}>
{(option) => (
<MenuV2.RadioItem value={option.id} class="capitalize" closeOnSelect>
{option.label}
</MenuV2.RadioItem>
)}
</For>
</MenuV2.RadioGroup>
</MenuV2.Content>
</MenuV2.Portal>
</MenuV2>
</TooltipV2>
)
}
@@ -688,8 +703,3 @@ function PromptInputV2SuggestionIcon(props: { item: PromptInputV2Suggestion }) {
/>
)
}
function keybindTitle(label: string, keybind?: string[]) {
if (!keybind?.length) return label
return `${label} (${keybind.join("+")})`
}
@@ -23,6 +23,7 @@ export type PromptInputV2SelectControl = {
options: Accessor<PromptInputV2Option[]>
current: Accessor<string>
onSelect: (id: string) => void
keybind?: Accessor<string[]>
}
export type PromptInputV2ViewConfig = {
+1 -1
View File
@@ -86,7 +86,7 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -96,7 +96,7 @@ Tabela ispod pruža procijenjeni broj zahtjeva na osnovu tipičnih obrazaca kori
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -96,7 +96,7 @@ Tabellen nedenfor giver et estimeret antal anmodninger baseret på typiske Go-fo
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -88,7 +88,7 @@ Die folgende Tabelle zeigt eine geschätzte Anzahl von Anfragen basierend auf ty
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -96,7 +96,7 @@ La siguiente tabla proporciona una cantidad estimada de peticiones basada en los
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ Le tableau ci-dessous fournit une estimation du nombre de requêtes basée sur d
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -94,7 +94,7 @@ La tabella seguente fornisce una stima del conteggio delle richieste in base a p
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ OpenCode Goには以下の制限が含まれています:
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ OpenCode Go에는 다음과 같은 한도가 포함됩니다.
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -96,7 +96,7 @@ Tabellen nedenfor gir et estimert antall forespørsler basert på typiske bruksm
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -90,7 +90,7 @@ Poniższa tabela przedstawia szacunkową liczbę żądań na podstawie typowych
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -96,7 +96,7 @@ A tabela abaixo fornece uma contagem estimada de requisições com base nos padr
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -96,7 +96,7 @@ OpenCode Go включает следующие лимиты:
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้:
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ Aşağıdaki tablo, tipik Go kullanım modellerine dayalı tahmini bir istek say
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ OpenCode Go 包含以下限制:
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |
+1 -1
View File
@@ -86,7 +86,7 @@ OpenCode Go 包含以下限制:
| Grok 4.5 | 120 | 300 | 600 |
| GLM-5.2 | 880 | 2,150 | 4,300 |
| GLM-5.1 | 880 | 2,150 | 4,300 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K3 | 110 | 250 | 490 |
| Kimi K2.7 Code | 1,350 | 4,630 | 9,250 |
| Kimi K2.6 | 1,150 | 2,880 | 5,750 |
| MiMo-V2.5 | 30,100 | 75,200 | 150,400 |