diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
index 1c41a66faa..15f865b742 100644
--- a/.github/workflows/publish.yml
+++ b/.github/workflows/publish.yml
@@ -339,7 +339,8 @@ jobs:
env:
OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }}
GH_TOKEN: ${{ steps.committer.outputs.token }}
- CSC_KEYCHAIN: build.keychain
+ CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }}
+ CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
APPLE_API_KEY: ${{ runner.temp }}/apple-api-key.p8
APPLE_API_KEY_ID: ${{ secrets.APPLE_API_KEY }}
APPLE_API_ISSUER: ${{ secrets.APPLE_API_ISSUER }}
diff --git a/bun.lock b/bun.lock
index e905ada8c5..4de04ab24d 100644
--- a/bun.lock
+++ b/bun.lock
@@ -29,7 +29,7 @@
},
"packages/app": {
"name": "@opencode-ai/app",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@corvu/drawer": "catalog:",
"@dnd-kit/abstract": "0.5.0",
@@ -96,7 +96,7 @@
},
"packages/cli": {
"name": "@opencode-ai/cli",
- "version": "1.18.11",
+ "version": "1.18.10",
"bin": {
"lildax": "./bin/lildax.cjs",
},
@@ -144,7 +144,7 @@
},
"packages/codemode": {
"name": "@opencode-ai/codemode",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"acorn": "8.15.0",
"effect": "catalog:",
@@ -158,7 +158,7 @@
},
"packages/console/app": {
"name": "@opencode-ai/console-app",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1",
@@ -194,7 +194,7 @@
},
"packages/console/core": {
"name": "@opencode-ai/console-core",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
@@ -221,7 +221,7 @@
},
"packages/console/function": {
"name": "@opencode-ai/console-function",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@ai-sdk/anthropic": "3.0.82",
"@ai-sdk/openai": "3.0.48",
@@ -243,7 +243,7 @@
},
"packages/console/mail": {
"name": "@opencode-ai/console-mail",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
@@ -267,7 +267,7 @@
},
"packages/console/support": {
"name": "@opencode-ai/console-support",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@opencode-ai/console-core": "workspace:*",
@@ -287,7 +287,7 @@
},
"packages/core": {
"name": "@opencode-ai/core",
- "version": "1.18.11",
+ "version": "1.18.10",
"bin": {
"opencode": "./bin/opencode",
},
@@ -381,10 +381,9 @@
},
"packages/desktop": {
"name": "@opencode-ai/desktop",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@zip.js/zip.js": "2.7.62",
- "drizzle-orm": "catalog:",
"effect": "catalog:",
"electron-context-menu": "4.1.2",
"electron-log": "^5",
@@ -435,7 +434,7 @@
},
"packages/effect-drizzle-sqlite": {
"name": "@opencode-ai/effect-drizzle-sqlite",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"drizzle-orm": "catalog:",
"effect": "catalog:",
@@ -449,7 +448,7 @@
},
"packages/effect-sqlite-node": {
"name": "@opencode-ai/effect-sqlite-node",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"effect": "catalog:",
},
@@ -461,7 +460,7 @@
},
"packages/enterprise": {
"name": "@opencode-ai/enterprise",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@hono/standard-validator": "catalog:",
"@opencode-ai/core": "workspace:*",
@@ -493,7 +492,7 @@
},
"packages/function": {
"name": "@opencode-ai/function",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@octokit/auth-app": "8.0.1",
"@octokit/rest": "catalog:",
@@ -509,7 +508,7 @@
},
"packages/http-recorder": {
"name": "@opencode-ai/http-recorder",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@effect/platform-node": "4.0.0-beta.83",
"@effect/platform-node-shared": "4.0.0-beta.83",
@@ -540,7 +539,7 @@
},
"packages/llm": {
"name": "@opencode-ai/llm",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@opencode-ai/schema": "workspace:*",
"@smithy/eventstream-codec": "4.2.14",
@@ -559,7 +558,7 @@
},
"packages/opencode": {
"name": "opencode",
- "version": "1.18.11",
+ "version": "1.18.10",
"bin": {
"opencode": "./bin/opencode",
},
@@ -690,7 +689,7 @@
},
"packages/plugin": {
"name": "@opencode-ai/plugin",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@ai-sdk/provider": "3.0.8",
"@opencode-ai/sdk": "workspace:*",
@@ -766,7 +765,7 @@
},
"packages/sdk/js": {
"name": "@opencode-ai/sdk",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"cross-spawn": "catalog:",
},
@@ -781,7 +780,7 @@
},
"packages/server": {
"name": "@opencode-ai/server",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@opencode-ai/core": "workspace:*",
"@opencode-ai/protocol": "workspace:*",
@@ -796,7 +795,7 @@
},
"packages/session-ui": {
"name": "@opencode-ai/session-ui",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode-ai/client": "file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz",
@@ -840,7 +839,7 @@
},
"packages/slack": {
"name": "@opencode-ai/slack",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@opencode-ai/sdk": "workspace:*",
"@slack/bolt": "^3.17.1",
@@ -853,7 +852,7 @@
},
"packages/stats/app": {
"name": "@opencode-ai/stats-app",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@ibm/plex": "6.4.1",
"@kobalte/core": "catalog:",
@@ -887,7 +886,7 @@
},
"packages/stats/core": {
"name": "@opencode-ai/stats-core",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@aws-sdk/client-athena": "3.933.0",
"@planetscale/database": "1.19.0",
@@ -906,7 +905,7 @@
},
"packages/stats/server": {
"name": "@opencode-ai/stats-server",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@aws-sdk/client-firehose": "3.933.0",
"@effect/platform-node": "catalog:",
@@ -948,7 +947,7 @@
},
"packages/tui": {
"name": "@opencode-ai/tui",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@opencode-ai/core": "workspace:*",
"@opencode-ai/plugin": "workspace:*",
@@ -975,7 +974,7 @@
},
"packages/ui": {
"name": "@opencode-ai/ui",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@kobalte/core": "catalog:",
"@pierre/diffs": "catalog:",
@@ -1027,7 +1026,7 @@
},
"packages/web": {
"name": "@opencode-ai/web",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1",
diff --git a/nix/hashes.json b/nix/hashes.json
index 25f0e76812..2fafb82c44 100644
--- a/nix/hashes.json
+++ b/nix/hashes.json
@@ -1,8 +1,8 @@
{
"nodeModules": {
- "x86_64-linux": "sha256-a7NyYa9vRUEqDfZNDPXXmFO58RDEgioyuGSl5CPBvxo=",
- "aarch64-linux": "sha256-l4OJtSEllHvRhktjcaJYwkXBSaJvsIoyoLusbZfYMcM=",
- "aarch64-darwin": "sha256-IIl0BQGs1/HLFh0auiQjiwfSQ2nfHcK2G2BAphYW59c=",
- "x86_64-darwin": "sha256-vVeuPyd4ZIRYrHouphTuEb4rkRZLKKTAHe840jNh9rU="
+ "x86_64-linux": "sha256-SiJd6uXrL/MqqFGN/uUcHh0Wzdlafnpx++VZa5gUCoE=",
+ "aarch64-linux": "sha256-pKcT34NYIHVasraRTx0ASTzyuFuIzBTxXg6+KSKvTps=",
+ "aarch64-darwin": "sha256-hzrym0KpiyYAv80eT/DjcSIJWYBUq4QDgDf6Wtot7jU=",
+ "x86_64-darwin": "sha256-Or5dSTdajUwij0XpovXSXjJ0LmRUcpcW5TJ4q4B0k0A="
}
}
diff --git a/packages/app/e2e/regression/project-picker-recent-search.spec.ts b/packages/app/e2e/regression/project-picker-recent-search.spec.ts
deleted file mode 100644
index 2cdb0b4a03..0000000000
--- a/packages/app/e2e/regression/project-picker-recent-search.spec.ts
+++ /dev/null
@@ -1,60 +0,0 @@
-import { expect, test } from "@playwright/test"
-import type { Page } from "@playwright/test"
-import { fixture, pageMessages } from "../smoke/session-timeline.fixture"
-import { mockOpenCodeServer } from "../utils/mock-server"
-import { expectAppVisible } from "../utils/waits"
-
-const NAMES = ["alpha-service", "bravo-web", "charlie-api", "delta-tools", "echo-infra", "foxtrot-docs"]
-const worktrees = NAMES.map((name) => `/opencode-demo/${name}`)
-
-// The sixth project sits outside the five-item recent cap, so it is only reachable if the
-// dialog hands every recent project to the list filter instead of a pre-truncated slice.
-const OUTSIDE_CAP = "foxtrot-docs"
-
-// Dialog rows carry data-directory-path; the sidebar project list does not, so this
-// scopes assertions to the picker instead of matching the sidebar entry of the same name.
-const rows = (page: Page) => page.locator("[data-directory-path]")
-const row = (page: Page, name: string) => page.locator(`[data-directory-path*="${name}"]`)
-
-async function openProjectDialog(page: Page) {
- await mockOpenCodeServer(page, {
- sessions: fixture.sessions,
- provider: fixture.provider,
- directory: fixture.directory,
- project: fixture.project,
- pageMessages,
- fileList: () => [],
- findFiles: () => [],
- })
- await page.addInitScript((dirs) => {
- localStorage.setItem(
- "opencode.global.dat:server",
- JSON.stringify({
- projects: { local: dirs.map((worktree: string) => ({ worktree, expanded: false })) },
- lastProject: {},
- }),
- )
- }, worktrees)
- await page.goto("/")
- const add = page.getByRole("button", { name: "Add project" }).first()
- await expectAppVisible(add)
- await add.click()
- await expect(rows(page)).toHaveCount(5)
- return page.getByRole("textbox").last()
-}
-
-test("searches every recent project, not just the five most recent", async ({ page }) => {
- const search = await openProjectDialog(page)
- await expect(row(page, OUTSIDE_CAP)).toHaveCount(0)
-
- await search.fill("foxtrot")
-
- await expect(row(page, OUTSIDE_CAP)).toHaveCount(1)
-})
-
-test("still caps the idle recent list at five projects", async ({ page }) => {
- await openProjectDialog(page)
-
- await expect(row(page, NAMES[4])).toHaveCount(1)
- await expect(row(page, OUTSIDE_CAP)).toHaveCount(0)
-})
diff --git a/packages/app/package.json b/packages/app/package.json
index 2dd4a05d86..e6e95e35ff 100644
--- a/packages/app/package.json
+++ b/packages/app/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/app",
- "version": "1.18.11",
+ "version": "1.18.10",
"description": "",
"type": "module",
"exports": {
diff --git a/packages/app/src/components/dialog-select-directory.tsx b/packages/app/src/components/dialog-select-directory.tsx
index fc248d821e..96bcedb9db 100644
--- a/packages/app/src/components/dialog-select-directory.tsx
+++ b/packages/app/src/components/dialog-select-directory.tsx
@@ -18,8 +18,6 @@ interface DialogSelectDirectoryProps {
server: ServerConnection.Any
}
-const RECENT_PROJECT_LIMIT = 5
-
type Row = {
absolute: string
search: string
@@ -104,6 +102,7 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) {
return projects
.map((project, index) => ({ project, at: byProject.get(project.worktree) ?? 0, index }))
.sort((a, b) => b.at - a.at || a.index - b.index)
+ .slice(0, 5)
.map(({ project }) => {
const row = toRow(project.worktree, home(), "recent")
const name = project.name || getFilename(project.worktree)
@@ -117,10 +116,7 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) {
const items = async (value: string) => {
const results = await directories(value)
const directoryRows = results.map((absolute) => toRow(absolute, home(), "folders"))
- // Cap the idle list only. Once a query narrows the results, every project stays searchable.
- const recent = recentProjects()
- const visible = value ? recent : recent.slice(0, RECENT_PROJECT_LIMIT)
- return uniqueRows([...visible, ...directoryRows])
+ return uniqueRows([...recentProjects(), ...directoryRows])
}
function resolve(absolute: string) {
diff --git a/packages/app/src/components/prompt-input-v2.tsx b/packages/app/src/components/prompt-input-v2.tsx
index 96b99aaf4a..2d6a5e98d6 100644
--- a/packages/app/src/components/prompt-input-v2.tsx
+++ b/packages/app/src/components/prompt-input-v2.tsx
@@ -344,7 +344,7 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
if (item?.commentID) comments.remove(item.path, item.commentID)
},
openAttachment: (attachment) =>
- dialog.show(() => ),
+ dialog.show(() => ),
openContext(key) {
const item = controller.contextItem(key)
if (item) openComment(item, props, sync, layout, files, comments)
@@ -377,7 +377,6 @@ export function usePromptInputV2Controller(props: PromptInputV2ControllerProps):
}),
readClipboardImage: platform.readClipboardImage,
getPathForFile: platform.getPathForFile,
- store: platform.draftStore?.putBlob,
},
view: {
placeholder: designPlaceholder,
diff --git a/packages/app/src/components/prompt-input.tsx b/packages/app/src/components/prompt-input.tsx
index 08c1ee3489..7923e18ee2 100644
--- a/packages/app/src/components/prompt-input.tsx
+++ b/packages/app/src/components/prompt-input.tsx
@@ -1489,7 +1489,7 @@ export const PromptInput: Component = (props) => {
- dialog.show(() => )
+ dialog.show(() => )
}
onRemove={removeAttachment}
removeLabel={language.t("prompt.attachment.remove")}
diff --git a/packages/app/src/components/prompt-input/attachments.ts b/packages/app/src/components/prompt-input/attachments.ts
index 6f3ef57c66..9568b17d19 100644
--- a/packages/app/src/components/prompt-input/attachments.ts
+++ b/packages/app/src/components/prompt-input/attachments.ts
@@ -3,13 +3,28 @@ import { makeEventListener } from "@solid-primitives/event-listener"
import { showToast } from "@/utils/toast"
import { type ContentPart, type ImageAttachmentPart, type usePrompt } from "@/context/prompt"
import { useLanguage } from "@/context/language"
-import { usePlatform } from "@/context/platform"
import { uuid } from "@/utils/uuid"
import { getCursorPosition } from "./editor-dom"
-import { createBlobReference, type DraftStore } from "@/utils/draft-store"
import { attachmentMime } from "./files"
import { normalizePaste, pasteMode } from "./paste"
+function dataUrl(file: File, mime: string) {
+ return new Promise((resolve) => {
+ const reader = new FileReader()
+ reader.addEventListener("error", () => resolve(""))
+ reader.addEventListener("load", () => {
+ const value = typeof reader.result === "string" ? reader.result : ""
+ const idx = value.indexOf(",")
+ if (idx === -1) {
+ resolve(value)
+ return
+ }
+ resolve(`data:${mime};base64,${value.slice(idx + 1)}`)
+ })
+ reader.readAsDataURL(file)
+ })
+}
+
type PromptTarget = Pick["capture"]>, "current" | "cursor" | "set">
type AttachmentTarget = { prompt: PromptTarget; cursor: number | undefined }
@@ -21,7 +36,6 @@ type PromptAttachmentsCoreInput = {
warn?: () => void
readClipboardImage?: () => Promise
getPathForFile?: (file: File) => string
- draftStore?: DraftStore
}
export type PromptAttachmentsInput = {
@@ -51,13 +65,16 @@ export function createPromptAttachmentsCore(input: PromptAttachmentsCoreInput) {
return false
}
+ const url = await dataUrl(file, mime)
+ if (!url) return false
+
const attachment: ImageAttachmentPart = {
type: "image",
id: uuid(),
filename: file.name,
sourcePath: input.getPathForFile?.(file) || undefined,
mime,
- blob: input.draftStore ? await input.draftStore.putBlob(file) : await createBlobReference(file),
+ dataUrl: url,
}
target.prompt.set([...target.prompt.current(), attachment], target.cursor)
return true
@@ -149,10 +166,8 @@ export function createPromptAttachmentsCore(input: PromptAttachmentsCoreInput) {
export function createPromptAttachments(input: PromptAttachmentsInput) {
const language = useLanguage()
- const platform = usePlatform()
const attachments = createPromptAttachmentsCore({
...input,
- draftStore: platform.draftStore,
capture: input.prompt.capture,
warn: () => {
showToast({
diff --git a/packages/app/src/components/prompt-input/build-request-parts.ts b/packages/app/src/components/prompt-input/build-request-parts.ts
index a1e3448b31..7f0fea2bfe 100644
--- a/packages/app/src/components/prompt-input/build-request-parts.ts
+++ b/packages/app/src/components/prompt-input/build-request-parts.ts
@@ -22,7 +22,7 @@ type ContextFile = {
type BuildRequestPartsInput = {
prompt: Prompt
context: ContextFile[]
- images: (Omit & { dataUrl: string })[]
+ images: ImageAttachmentPart[]
text: string
messageID: string
sessionID: string
diff --git a/packages/app/src/components/prompt-input/history-store.ts b/packages/app/src/components/prompt-input/history-store.ts
index 3858b8b9bc..b64636f3c0 100644
--- a/packages/app/src/components/prompt-input/history-store.ts
+++ b/packages/app/src/components/prompt-input/history-store.ts
@@ -1,13 +1,7 @@
import { createStore, type SetStoreFunction, type Store } from "solid-js/store"
import type { Prompt } from "@/context/prompt"
import { Persist, persisted } from "@/utils/persist"
-import {
- clonePromptHistoryComments,
- clonePromptParts,
- prependHistoryEntry,
- type PromptHistoryComment,
- type PromptHistoryStoredEntry,
-} from "./history"
+import { prependHistoryEntry, type PromptHistoryComment, type PromptHistoryStoredEntry } from "./history"
export type PromptInputHistory = {
entries: (mode: "normal" | "shell") => PromptHistoryStoredEntry[]
@@ -41,23 +35,13 @@ export function createPromptInputHistory(): PromptInputHistory {
}
export function createPersistedPromptInputHistory() {
- const [normal, setNormal, normalInit] = persisted(
- Persist.prompt(Persist.global("prompt-history", ["prompt-history.v1"])),
+ const [normal, setNormal] = persisted(
+ Persist.global("prompt-history", ["prompt-history.v1"]),
createStore({ entries: [] }),
)
- const [shell, setShell, shellInit] = persisted(
- Persist.prompt(Persist.global("prompt-history-shell", ["prompt-history-shell.v1"])),
+ const [shell, setShell] = persisted(
+ Persist.global("prompt-history-shell", ["prompt-history-shell.v1"]),
createStore({ entries: [] }),
)
- const history = createPromptInputHistoryStore(normal, setNormal, shell, setShell)
- return {
- ...history,
- add(prompt: Prompt, mode: "normal" | "shell", comments: PromptHistoryComment[]) {
- const ready = mode === "shell" ? shellInit : normalInit
- if (!(ready instanceof Promise)) return history.add(prompt, mode, comments)
- const saved = clonePromptParts(prompt)
- const metadata = clonePromptHistoryComments(comments)
- void ready.then(() => history.add(saved, mode, metadata))
- },
- }
+ return createPromptInputHistoryStore(normal, setNormal, shell, setShell)
}
diff --git a/packages/app/src/components/prompt-input/history.test.ts b/packages/app/src/components/prompt-input/history.test.ts
index 94f24ce935..5e9c2c66ea 100644
--- a/packages/app/src/components/prompt-input/history.test.ts
+++ b/packages/app/src/components/prompt-input/history.test.ts
@@ -112,7 +112,7 @@ describe("prompt-input history", () => {
end: 12,
selection: { startLine: 1, startChar: 1, endLine: 2, endChar: 1 },
},
- { type: "image", id: "1", filename: "img.png", mime: "image/png", blob: { id: "blob", url: "blob:test" } },
+ { type: "image", id: "1", filename: "img.png", mime: "image/png", dataUrl: "data:image/png;base64,abc" },
]
const copy = clonePromptParts(original)
expect(copy).not.toBe(original)
diff --git a/packages/app/src/components/prompt-input/image-attachments.tsx b/packages/app/src/components/prompt-input/image-attachments.tsx
index ecc38db888..3a0cc3e4dd 100644
--- a/packages/app/src/components/prompt-input/image-attachments.tsx
+++ b/packages/app/src/components/prompt-input/image-attachments.tsx
@@ -100,7 +100,7 @@ export const PromptImageAttachments: Component = (p
}
>
props.onOpen(attachment)}
diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts
index c82c3a4399..051bf4d06c 100644
--- a/packages/app/src/components/prompt-input/submit.ts
+++ b/packages/app/src/components/prompt-input/submit.ts
@@ -22,7 +22,6 @@ import { ScopedKey } from "@/utils/server-scope"
import { createPromptSubmissionState } from "./submission-state"
import { normalizeSessionInfo } from "@/utils/session"
import { Event } from "@opencode-ai/schema/event"
-import { blobDataUrl } from "@/utils/draft-store"
type PendingPrompt = {
abort: AbortController
@@ -96,12 +95,10 @@ export async function sendFollowupDraft(input: FollowupSendInput) {
providerID: input.draft.model.providerID,
variant: input.draft.variant,
},
- files: await Promise.all(
- images.map(async (attachment) => ({
- uri: await blobDataUrl(attachment.blob, attachment.mime),
- name: attachment.filename,
- })),
- ),
+ files: images.map((attachment) => ({
+ uri: attachment.dataUrl,
+ name: attachment.filename,
+ })),
})
return true
} catch (err) {
@@ -111,16 +108,10 @@ export async function sendFollowupDraft(input: FollowupSendInput) {
}
const messageID = input.messageID ?? Identifier.ascending("message")
- const encodedImages = await Promise.all(
- images.map(async (attachment) => ({
- ...attachment,
- dataUrl: await blobDataUrl(attachment.blob, attachment.mime),
- })),
- )
const { requestParts, optimisticParts } = buildRequestParts({
prompt: input.draft.prompt,
context: input.draft.context,
- images: encodedImages,
+ images,
text,
sessionID: input.draft.sessionID,
messageID,
@@ -525,12 +516,10 @@ export function createPromptSubmit(input: PromptSubmitInput) {
arguments: args.join(" "),
agent,
model: { id: model.modelID, providerID: model.providerID, variant },
- files: await Promise.all(
- images.map(async (attachment) => ({
- uri: await blobDataUrl(attachment.blob, attachment.mime),
- name: attachment.filename,
- })),
- ),
+ files: images.map((attachment) => ({
+ uri: attachment.dataUrl,
+ name: attachment.filename,
+ })),
})
.catch((err) => {
serverSync().session.set("session_status", session.id, { type: "idle" })
diff --git a/packages/app/src/context/global-sync/bootstrap.test.ts b/packages/app/src/context/global-sync/bootstrap.test.ts
index a95706a3db..71986dd3c4 100644
--- a/packages/app/src/context/global-sync/bootstrap.test.ts
+++ b/packages/app/src/context/global-sync/bootstrap.test.ts
@@ -8,7 +8,6 @@ import {
bootstrapDirectory,
loadAgentsQuery,
loadCommands,
- loadGlobalConfigQuery,
loadPathQuery,
loadProjectsQuery,
loadProvidersQuery,
@@ -77,7 +76,6 @@ function directoryState() {
describe("bootstrapDirectory", () => {
test("uses legacy MCP endpoints while refreshing a v1 directory", async () => {
- const legacyConfigReads: string[] = []
const mcpReads: string[] = []
const [store, setStore] = directoryState()
@@ -93,12 +91,7 @@ describe("bootstrapDirectory", () => {
},
sdk: {
app: { agents: async () => ({ data: [{ name: "build", mode: "primary" }] }) },
- config: {
- get: async () => {
- legacyConfigReads.push("directory")
- return { data: {} }
- },
- },
+ config: { get: async () => ({ data: {} }) },
session: { status: async () => ({ data: {} }) },
vcs: { get: async () => ({ data: undefined }) },
command: {
@@ -141,88 +134,8 @@ describe("bootstrapDirectory", () => {
await new Promise((resolve) => setTimeout(resolve, 80))
expect(store.status).toBe("complete")
- expect(legacyConfigReads).toEqual(["directory"])
expect(mcpReads.sort()).toEqual(["command", "resource", "status"])
})
-
- test("skips legacy config while refreshing a v2 directory", async () => {
- const [store, setStore] = directoryState()
-
- await bootstrapDirectory({
- directory: "/project",
- scope: ServerScope.local,
- mcp: false,
- global: {
- config: {} satisfies Config,
- path: { state: "", config: "", worktree: "/project", directory: "/project", home: "/home" },
- project: [{ id: "project", worktree: "/project" } as Project],
- provider,
- },
- sdk: {
- config: {
- get: async () => {
- throw new Error("legacy directory config should not be called")
- },
- },
- } as unknown as OpencodeClient,
- api,
- store,
- setStore,
- vcsCache: { setStore() {} } as unknown as VcsCache,
- loadSessions() {},
- translate: (key) => key,
- queryClient: new QueryClient(),
- protocol: Promise.resolve("v2"),
- })
-
- expect(store.status).toBe("partial")
-
- await new Promise((resolve) => setTimeout(resolve, 80))
-
- expect(store.status).toBe("complete")
- })
-})
-
-describe("config queries", () => {
- test("skips legacy global config for v2 servers", async () => {
- const sdk = {
- global: {
- config: {
- get: async () => {
- throw new Error("legacy global config should not be called")
- },
- },
- },
- } as unknown as OpencodeClient
-
- const result = await new QueryClient().fetchQuery(
- loadGlobalConfigQuery(ServerScope.local, sdk, Promise.resolve("v2")),
- )
-
- expect(result).toEqual({})
- })
-
- test("loads legacy global config for v1 servers", async () => {
- const calls: string[] = []
- const config = { shell: "zsh" } satisfies Config
- const sdk = {
- global: {
- config: {
- get: async () => {
- calls.push("global")
- return { data: config }
- },
- },
- },
- } as unknown as OpencodeClient
-
- const result = await new QueryClient().fetchQuery(
- loadGlobalConfigQuery(ServerScope.local, sdk, Promise.resolve("v1")),
- )
-
- expect(result).toEqual(config)
- expect(calls).toEqual(["global"])
- })
})
describe("query keys", () => {
diff --git a/packages/app/src/context/global-sync/bootstrap.ts b/packages/app/src/context/global-sync/bootstrap.ts
index 0f3e473816..39221d551f 100644
--- a/packages/app/src/context/global-sync/bootstrap.ts
+++ b/packages/app/src/context/global-sync/bootstrap.ts
@@ -105,13 +105,10 @@ function showErrors(input: {
})
}
-export const loadGlobalConfigQuery = (scope: ServerScope, sdk: OpencodeClient, protocol?: Promise) =>
+export const loadGlobalConfigQuery = (scope: ServerScope, sdk: OpencodeClient) =>
queryOptions({
queryKey: [scope, "config"],
- queryFn: async () => {
- if ((await protocol) !== "v1") return {}
- return retry(() => sdk.global.config.get().then((x) => x.data!))
- },
+ queryFn: () => retry(() => sdk.global.config.get().then((x) => x.data!)),
})
type ProjectApi = {
@@ -152,7 +149,7 @@ export async function bootstrapGlobal(input: {
queryClient: QueryClient
}) {
const slow = [
- () => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.scope, input.serverSDK, input.protocol)),
+ () => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.scope, input.serverSDK)),
() =>
input.queryClient.fetchQuery(
loadProvidersQuery(input.scope, null, input.serverAPI, input.serverSDK, input.protocol),
@@ -379,10 +376,7 @@ export async function bootstrapDirectory(input: {
.ensureQueryData(loadAgentsQuery(input.scope, input.directory, input.api.agent, input.sdk, input.protocol))
.then((data) => input.setStore("agent", data)),
() =>
- retry(async () => {
- if ((await input.protocol) !== "v1") return
- return input.sdk.config.get().then((x) => input.setStore("config", reconcile(x.data!, { merge: false })))
- }),
+ retry(() => input.sdk.config.get().then((x) => input.setStore("config", reconcile(x.data!, { merge: false })))),
() =>
retry(() =>
(async () => {
diff --git a/packages/app/src/context/platform.tsx b/packages/app/src/context/platform.tsx
index 0408b233ff..08686361c5 100644
--- a/packages/app/src/context/platform.tsx
+++ b/packages/app/src/context/platform.tsx
@@ -5,7 +5,6 @@ import type { DesktopMenuAction } from "../desktop-menu"
import { ServerConnection } from "./server"
import type { WslServersPlatform } from "../wsl/types"
import type { UpdaterPlatform } from "../updater"
-import type { DraftStore } from "@/utils/draft-store"
type PickerPaths = string | string[] | null
type OpenDirectoryPickerOptions = { title?: string; multiple?: boolean }
@@ -65,9 +64,6 @@ type PlatformBase = {
/** Storage mechanism, defaults to localStorage */
storage?: (name?: string) => SyncStorage | AsyncStorage
- /** Prompt drafts, history, and their blobs. */
- draftStore?: DraftStore
-
/** Stable platform window identity for window-scoped persistence */
windowID?: string
diff --git a/packages/app/src/context/prompt-state.ts b/packages/app/src/context/prompt-state.ts
index ea639a5bdd..73196289e2 100644
--- a/packages/app/src/context/prompt-state.ts
+++ b/packages/app/src/context/prompt-state.ts
@@ -5,7 +5,6 @@ import { createStore, type SetStoreFunction } from "solid-js/store"
import type { FileSelection } from "@/context/file"
import { Persist, persisted } from "@/utils/persist"
import type { ServerScope } from "@/utils/server-scope"
-import type { BlobReference } from "@/utils/draft-store"
interface PartBase {
content: string
@@ -38,7 +37,7 @@ export interface ImageAttachmentPart {
filename: string
sourcePath?: string
mime: string
- blob: BlobReference
+ dataUrl: string
}
export type ContentPart = TextPart | FileAttachmentPart | AgentPart | ImageAttachmentPart
@@ -169,9 +168,9 @@ function createPromptActions(setStore: SetStoreFunction) {
}
function promptTarget(serverScope: ServerScope, scope: PromptScope) {
- if ("draftID" in scope) return Persist.prompt(Persist.draft(scope.draftID, "prompt"))
+ if ("draftID" in scope) return Persist.draft(scope.draftID, "prompt")
const legacy = `${scope.dir}/prompt${scope.id ? "/" + scope.id : ""}.v2`
- return Persist.prompt(Persist.serverScoped(serverScope, scope.dir, scope.id, "prompt", [legacy]))
+ return Persist.serverScoped(serverScope, scope.dir, scope.id, "prompt", [legacy])
}
function promptStore(initial?: InitialPrompt): PromptStore {
@@ -246,7 +245,7 @@ export function createPromptSession(serverScope: ServerScope, scope: PromptScope
}
export function createDraftPromptSession(draftID: string, initial?: InitialPrompt) {
- return createPersistedPrompt(Persist.prompt(Persist.draft(draftID, "prompt")), initial)
+ return createPersistedPrompt(Persist.draft(draftID, "prompt"), initial)
}
export type PromptSession = ReturnType
diff --git a/packages/app/src/context/server-sync.tsx b/packages/app/src/context/server-sync.tsx
index 13a0b74bc6..196cda8479 100644
--- a/packages/app/src/context/server-sync.tsx
+++ b/packages/app/src/context/server-sync.tsx
@@ -184,7 +184,7 @@ function makeQueryOptionsApi(
protocol: Promise<"v1" | "v2">,
) {
return {
- globalConfig: () => loadGlobalConfigQuery(scope, serverSDK(), protocol),
+ globalConfig: () => loadGlobalConfigQuery(scope, serverSDK()),
projects: () => loadProjectsQuery(scope, serverAPI.project),
providers: (directory: PathKey | null) =>
loadProvidersQuery(scope, directory, serverAPI, directory ? sdkFor(directory) : serverSDK(), protocol),
diff --git a/packages/app/src/context/tabs.tsx b/packages/app/src/context/tabs.tsx
index b6608e8681..e4d50ac161 100644
--- a/packages/app/src/context/tabs.tsx
+++ b/packages/app/src/context/tabs.tsx
@@ -101,10 +101,7 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({
}
const removeDraftPersisted = (draftID: string) => {
- for (const key of draftPersistedKeys()) {
- const target = Persist.draft(draftID, key)
- removePersisted(key === "prompt" ? Persist.prompt(target) : target, platform)
- }
+ for (const key of draftPersistedKeys()) removePersisted(Persist.draft(draftID, key), platform)
}
const removeInfo = (key: string) => {
diff --git a/packages/app/src/entry.tsx b/packages/app/src/entry.tsx
index 9b71d6567e..6823d1c6d7 100644
--- a/packages/app/src/entry.tsx
+++ b/packages/app/src/entry.tsx
@@ -4,7 +4,6 @@ import * as Sentry from "@sentry/solid"
import { render } from "solid-js/web"
import { AppBaseProviders, AppInterface } from "@/app"
import { type Platform, PlatformProvider } from "@/context/platform"
-import { createBrowserDraftStore } from "@/utils/draft-store"
import { dict as en } from "@/i18n/en"
import { dict as zh } from "@/i18n/zh"
import { authFromToken } from "@/utils/server"
@@ -117,7 +116,6 @@ const clearAuthToken = () => {
const platform: Platform = {
platform: "web",
- draftStore: createBrowserDraftStore(),
version: pkg.version,
openExternal,
restart,
diff --git a/packages/app/src/index.ts b/packages/app/src/index.ts
index 8d36086d9f..2267ebf081 100644
--- a/packages/app/src/index.ts
+++ b/packages/app/src/index.ts
@@ -27,4 +27,3 @@ export {
type WslServersState,
} from "./wsl/types"
export { ServerConnection } from "./context/server"
-export { createDraftStore, type DraftStore } from "./utils/draft-store"
diff --git a/packages/app/src/pages/session/timeline/rows-current.test.ts b/packages/app/src/pages/session/timeline/rows-current.test.ts
index a5952a5e66..32a1d5f57c 100644
--- a/packages/app/src/pages/session/timeline/rows-current.test.ts
+++ b/packages/app/src/pages/session/timeline/rows-current.test.ts
@@ -167,41 +167,4 @@ describe("current session timeline rows", () => {
"thinking:msg_2",
])
})
-
- test("removes a failed assistant error when the turn continues streaming", () => {
- const source = [
- { id: "msg_user", type: "user", text: "recover", time: { created: 1 } },
- {
- id: "msg_failed",
- type: "assistant",
- agent: "build",
- model: { id: "model", providerID: "provider" },
- content: [],
- error: { type: "ProviderError", message: "temporary failure" },
- time: { created: 2, completed: 3 },
- },
- {
- id: "msg_recovery",
- type: "assistant",
- agent: "build",
- model: { id: "model", providerID: "provider" },
- content: [{ type: "text", text: "streaming again" }],
- time: { created: 4 },
- },
- ] satisfies SessionMessageInfo[]
- const normalized = normalizeSessionMessages("ses_1", source)
- const messages = new Map(normalized.messages.map((message) => [message.id, message]))
-
- const result = Timeline.constructSessionMessageRows(
- source,
- (messageID) => messages.get(messageID),
- (messageID) => normalized.parts.get(messageID) ?? [],
- true,
- "busy",
- true,
- normalized.messages.filter((message) => message.role === "user"),
- )
-
- expect(result.rows.map((row) => row._tag)).toEqual(["UserMessage", "AssistantPart"])
- })
})
diff --git a/packages/app/src/pages/session/timeline/rows.ts b/packages/app/src/pages/session/timeline/rows.ts
index 879646e86a..25a5113344 100644
--- a/packages/app/src/pages/session/timeline/rows.ts
+++ b/packages/app/src/pages/session/timeline/rows.ts
@@ -116,8 +116,7 @@ export namespace Timeline {
const compaction = userParts.some((p) => p.type === "compaction")
const interruptedMessageIndex = assistantMessages.findIndex((m) => m.error?.name === "MessageAbortedError")
const interrupted = interruptedMessageIndex !== -1
- const latestError = assistantMessages.at(-1)?.error
- const error = latestError?.name === "MessageAbortedError" ? undefined : latestError
+ const error = assistantMessages.find((m) => m.error && m.error.name !== "MessageAbortedError")?.error
const assistantPartRefs = assistantMessages.flatMap((message, messageIndex) =>
getMessageParts(message.id)
diff --git a/packages/app/src/utils/draft-store.ts b/packages/app/src/utils/draft-store.ts
deleted file mode 100644
index cd0895f52c..0000000000
--- a/packages/app/src/utils/draft-store.ts
+++ /dev/null
@@ -1,171 +0,0 @@
-import type { AsyncStorage } from "@solid-primitives/storage"
-
-export type BlobReference = { id: string; url: string }
-
-type Driver = {
- get(key: string): Promise
- set(key: string, value: string): Promise
- remove(key: string): Promise
- putBlob(blob: Blob): Promise
- getBlob(id: string): Promise
-}
-
-export type DraftStore = AsyncStorage & { putBlob(blob: Blob): Promise }
-const urls = new Map()
-
-function blobUrl(id: string, blob: Blob) {
- const existing = urls.get(id)
- if (existing) return existing
- const url = URL.createObjectURL(blob)
- urls.set(id, url)
- return url
-}
-
-async function blobID(blob: Blob) {
- const id = Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", await blob.arrayBuffer())))
- .map((byte) => byte.toString(16).padStart(2, "0"))
- .join("")
- return id
-}
-
-export async function createBlobReference(blob: Blob): Promise {
- const id = await blobID(blob)
- return { id, url: blobUrl(id, blob) }
-}
-
-export function createDraftStore(driver: Driver): DraftStore {
- const versions = new Map()
- const putBlob = async (blob: Blob) => {
- const id = await driver.putBlob(blob)
- return { id, url: blobUrl(id, blob) }
- }
- const encode = async (value: unknown): Promise => {
- if (Array.isArray(value)) return Promise.all(value.map(encode))
- if (!value || typeof value !== "object") return value
- const item = value as Record
- if (item.type === "image" && typeof item.dataUrl === "string") {
- const blob = await fetch(item.dataUrl).then((response) => response.blob())
- const { dataUrl: _, ...rest } = item
- return { ...rest, blob: { id: await driver.putBlob(blob) } }
- }
- if ("blob" in item && item.blob && typeof item.blob === "object") {
- const blob = item.blob as Record
- if (typeof blob.id === "string" && blob.id.startsWith("data:")) {
- const data = await fetch(blob.id).then((response) => response.blob())
- return { ...item, blob: { id: await driver.putBlob(data) } }
- }
- return { ...item, blob: { id: blob.id } }
- }
- return Object.fromEntries(
- await Promise.all(Object.entries(item).map(async ([key, entry]) => [key, await encode(entry)])),
- )
- }
- const decode = async (value: unknown): Promise => {
- if (Array.isArray(value)) return Promise.all(value.map(decode))
- if (!value || typeof value !== "object") return value
- const item = value as Record
- if (item.blob && typeof item.blob === "object") {
- const ref = item.blob as Record
- if (typeof ref.id === "string") {
- const blob = await driver.getBlob(ref.id)
- if (blob) return { ...item, blob: { id: ref.id, url: blobUrl(ref.id, blob) } }
- }
- }
- return Object.fromEntries(
- await Promise.all(Object.entries(item).map(async ([key, entry]) => [key, await decode(entry)])),
- )
- }
- return {
- getItem: async (key) => {
- const value = await driver.get(key)
- return value === null ? null : JSON.stringify(await decode(JSON.parse(value)))
- },
- setItem: async (key, value) => {
- const version = (versions.get(key) ?? 0) + 1
- versions.set(key, version)
- const encoded = JSON.stringify(await encode(JSON.parse(value)))
- if (versions.get(key) === version) await driver.set(key, encoded)
- },
- removeItem: async (key) => {
- versions.set(key, (versions.get(key) ?? 0) + 1)
- await driver.remove(key)
- },
- putBlob,
- }
-}
-
-export function createBrowserDraftStore(): DraftStore {
- const request = indexedDB.open("opencode-drafts", 1)
- request.addEventListener("upgradeneeded", () => {
- request.result.createObjectStore("documents")
- request.result.createObjectStore("blobs")
- })
- const db = new Promise((resolve, reject) => {
- request.addEventListener("success", () => {
- const database = request.result
- const transaction = database.transaction(["documents", "blobs"], "readwrite")
- const documents = transaction.objectStore("documents").getAll()
- documents.addEventListener("success", () => {
- const used = new Set()
- JSON.parse(`[${documents.result.join(",")}]`, (_key, item) => {
- if (item?.blob && typeof item.blob.id === "string") used.add(item.blob.id)
- return item
- })
- const blobs = transaction.objectStore("blobs").openKeyCursor()
- blobs.addEventListener("success", () => {
- const cursor = blobs.result
- if (!cursor) return
- if (!used.has(String(cursor.key))) cursor.delete()
- cursor.continue()
- })
- })
- transaction.addEventListener("complete", () => resolve(database))
- transaction.addEventListener("abort", () => resolve(database))
- })
- request.addEventListener("error", () => reject(request.error))
- })
- const get = async (store: string, key: string) => {
- const result = (await db).transaction(store).objectStore(store).get(key)
- return new Promise((resolve, reject) => {
- result.addEventListener("success", () => resolve(result.result))
- result.addEventListener("error", () => reject(result.error))
- })
- }
- const write = async (store: string, key: string, value?: unknown) => {
- const transaction = (await db).transaction(store, "readwrite")
- if (value === undefined) transaction.objectStore(store).delete(key)
- else transaction.objectStore(store).put(value, key)
- return new Promise((resolve, reject) => {
- transaction.addEventListener("complete", () => resolve())
- transaction.addEventListener("error", () => reject(transaction.error))
- })
- }
- return createDraftStore({
- get: async (key) => ((await get("documents", key)) as string | undefined) ?? null,
- set: (key, value) => write("documents", key, value),
- remove: (key) => write("documents", key),
- putBlob: async (blob) => {
- const id = await blobID(blob)
- await write("blobs", id, blob)
- return id
- },
- getBlob: async (id) => ((await get("blobs", id)) as Blob | undefined) ?? null,
- })
-}
-
-export async function blobDataUrl(blob: BlobReference, mime: string) {
- const data = await fetch(blob.url).then((response) => response.blob())
- return new Promise((resolve, reject) => {
- const reader = new FileReader()
- reader.addEventListener("error", () => reject(reader.error))
- reader.addEventListener("load", () => {
- const value = typeof reader.result === "string" ? reader.result : ""
- resolve(`data:${mime};base64,${value.slice(value.indexOf(",") + 1)}`)
- })
- reader.readAsDataURL(data)
- })
-}
-
-export function createLegacyBlobReference(dataUrl: string): BlobReference {
- return { id: dataUrl, url: dataUrl }
-}
diff --git a/packages/app/src/utils/persist.ts b/packages/app/src/utils/persist.ts
index a7742c399e..a2daae4866 100644
--- a/packages/app/src/utils/persist.ts
+++ b/packages/app/src/utils/persist.ts
@@ -15,7 +15,6 @@ type PersistedWithReady = [
]
type PersistTarget = {
- draft?: boolean
storage?: string
scope?: "window"
legacyStorageNames?: string[]
@@ -296,14 +295,6 @@ async function removeAsync(storage: AsyncStorage, key: string) {
} catch {}
}
-function toAsyncStorage(storage: SyncStorage | AsyncStorage): AsyncStorage {
- return {
- getItem: async (key) => storage.getItem(key),
- setItem: async (key, value) => storage.setItem(key, value),
- removeItem: async (key) => storage.removeItem(key),
- }
-}
-
async function migrateLegacyAsync(input: {
current: AsyncStorage
legacyStore?: AsyncStorage
@@ -522,9 +513,6 @@ export const Persist = {
if (session) return Persist.serverSession(scope, dir, session, key, legacy)
return Persist.serverWorkspace(scope, dir, key, legacy)
},
- prompt(target: PersistTarget): PersistTarget {
- return { ...target, draft: true }
- },
}
function resolveTarget(target: PersistTarget, platform: Platform): PersistTarget {
@@ -538,12 +526,9 @@ function resolveTarget(target: PersistTarget, platform: Platform): PersistTarget
}
export function removePersisted(
- target: { draft?: boolean; storage?: string; legacyStorageNames?: string[]; key: string },
+ target: { storage?: string; legacyStorageNames?: string[]; key: string },
platform?: Platform,
) {
- if (target.draft && platform?.draftStore) {
- void platform.draftStore.removeItem(`${target.storage ?? "default"}:${target.key}`)
- }
const isDesktop = platform?.platform === "desktop" && !!platform.storage
if (isDesktop) {
@@ -576,17 +561,8 @@ export function persisted(
const legacy = config.legacy ?? []
const isDesktop = platform.platform === "desktop" && !!platform.storage
- const draft = config.draft ? platform.draftStore : undefined
const currentStorage = (() => {
- if (draft) {
- const prefix = `${config.storage ?? "default"}:`
- return {
- getItem: (key: string) => draft.getItem(prefix + key),
- setItem: (key: string, value: string) => draft.setItem(prefix + key, value),
- removeItem: (key: string) => draft.removeItem(prefix + key),
- } satisfies AsyncStorage
- }
if (isDesktop) return platform.storage?.(config.storage)
if (!config.storage) return localStorageDirect()
return localStorageWithPrefix(config.storage)
@@ -601,7 +577,7 @@ export function persisted(
const legacyStorageNames = config.legacyStorageNames ?? []
const storage = (() => {
- if (!isDesktop && !draft) {
+ if (!isDesktop) {
const current = currentStorage as SyncStorage
const legacyStore = legacyStorage as SyncStorage
const legacyStores = legacyStorageNames.map(localStorageWithPrefix)
@@ -633,26 +609,15 @@ export function persisted(
const current = currentStorage as AsyncStorage
const legacyStore = legacyStorage as AsyncStorage | undefined
- const oldCurrent = draft
- ? isDesktop
- ? platform.storage?.(config.storage)
- : config.storage
- ? localStorageWithPrefix(config.storage)
- : localStorageDirect()
- : undefined
- const legacyStores = [
- oldCurrent,
- ...legacyStorageNames.map((name) => (isDesktop ? platform.storage?.(name) : localStorageWithPrefix(name))),
- ]
+ const legacyStores = legacyStorageNames
+ .map((name) => platform.storage?.(name) as AsyncStorage | undefined)
.filter((x) => !!x)
- .map(toAsyncStorage)
- let draftLatest: string | undefined
const api: AsyncStorage = {
getItem: async (key) => {
const value = await readCurrentAsync({ storage: current, key, defaults, migrate: config.migrate })
if (value !== undefined) return value
- const migrated = await migrateLegacyAsync({
+ return migrateLegacyAsync({
current,
legacyStore,
stores: legacyStores,
@@ -661,15 +626,8 @@ export function persisted(
defaults,
migrate: config.migrate,
})
- if (draftLatest === undefined) {
- if (draft && migrated !== null) return (await current.getItem(key)) ?? migrated
- return migrated
- }
- await current.setItem(key, draftLatest)
- return draftLatest
},
setItem: async (key, value) => {
- if (draft) draftLatest = value
await current.setItem(key, value)
},
removeItem: async (key) => {
diff --git a/packages/app/src/utils/prompt.test.ts b/packages/app/src/utils/prompt.test.ts
index 8b86d43b90..1ecaf02c97 100644
--- a/packages/app/src/utils/prompt.test.ts
+++ b/packages/app/src/utils/prompt.test.ts
@@ -37,18 +37,8 @@ describe("extractPromptFromParts", () => {
expect(result).toHaveLength(3)
expect(result[0]).toMatchObject({ type: "text", content: "check these" })
expect(result.slice(1)).toMatchObject([
- {
- type: "image",
- filename: "a.png",
- mime: "image/png",
- blob: expect.objectContaining({ id: expect.any(String) }),
- },
- {
- type: "image",
- filename: "b.pdf",
- mime: "application/pdf",
- blob: expect.objectContaining({ id: expect.any(String) }),
- },
+ { type: "image", filename: "a.png", mime: "image/png", dataUrl: "data:image/png;base64,AAA" },
+ { type: "image", filename: "b.pdf", mime: "application/pdf", dataUrl: "data:application/pdf;base64,BBB" },
])
})
})
diff --git a/packages/app/src/utils/prompt.ts b/packages/app/src/utils/prompt.ts
index 67d32086bb..35aec0071a 100644
--- a/packages/app/src/utils/prompt.ts
+++ b/packages/app/src/utils/prompt.ts
@@ -1,6 +1,5 @@
import type { AgentPart as MessageAgentPart, FilePart, Part, TextPart } from "@opencode-ai/sdk/v2"
import type { AgentPart, FileAttachmentPart, ImageAttachmentPart, Prompt } from "@/context/prompt"
-import { createLegacyBlobReference } from "@/utils/draft-store"
type Inline =
| {
@@ -108,7 +107,7 @@ export function extractPromptFromParts(parts: Part[], opts?: { directory?: strin
id: filePart.id,
filename: filePart.filename ?? attachmentName,
mime: filePart.mime,
- blob: createLegacyBlobReference(filePart.url),
+ dataUrl: filePart.url,
})
}
}
diff --git a/packages/app/test-browser/prompt-persistence.test.ts b/packages/app/test-browser/prompt-persistence.test.ts
index f3d8f8ae4f..a7b08078d7 100644
--- a/packages/app/test-browser/prompt-persistence.test.ts
+++ b/packages/app/test-browser/prompt-persistence.test.ts
@@ -2,7 +2,6 @@ import { beforeAll, describe, expect, mock, test } from "bun:test"
import type { AsyncStorage } from "@solid-primitives/storage"
import { createEffect, createRoot } from "solid-js"
import { ServerScope } from "@/utils/server-scope"
-import { createDraftStore } from "@/utils/draft-store"
let Prompt: typeof import("@/context/prompt")
let read: ((value: string | null) => void) | undefined
@@ -31,7 +30,7 @@ beforeAll(async () => {
}),
}))
mock.module("@/context/platform", () => ({
- usePlatform: () => ({ platform: "desktop", storage: () => storage, draftStore: storage }),
+ usePlatform: () => ({ platform: "desktop", storage: () => storage }),
}))
Prompt = await import("@/context/prompt")
@@ -70,50 +69,3 @@ describe("prompt persistence", () => {
})
})
})
-
-test("moves legacy image data URLs into blobs and hydrates object URLs", async () => {
- const documents = new Map()
- const blobs = new Map()
- const store = createDraftStore({
- get: async (key) => documents.get(key) ?? null,
- set: async (key, value) => void documents.set(key, value),
- remove: async (key) => void documents.delete(key),
- putBlob: async (blob) => {
- const id = String(blob.size)
- blobs.set(id, blob)
- return id
- },
- getBlob: async (id) => blobs.get(id) ?? null,
- })
-
- await store.setItem("prompt", JSON.stringify({ prompt: [{ type: "image", dataUrl: "data:image/png;base64,YQ==" }] }))
- expect(documents.get("prompt")).not.toContain("dataUrl")
- const value = JSON.parse((await store.getItem("prompt"))!)
- expect(value.prompt[0].blob.id).toBe("1")
- expect(value.prompt[0].blob.url).toStartWith("blob:")
-})
-
-test("does not let delayed blob migration overwrite a newer draft", async () => {
- const documents = new Map()
- const migration = Promise.withResolvers()
- const store = createDraftStore({
- get: async () => null,
- set: async (key, value) => void documents.set(key, value),
- remove: async () => undefined,
- putBlob: async () => {
- await migration.promise
- return "blob"
- },
- getBlob: async () => null,
- })
- const older = store.setItem(
- "prompt",
- JSON.stringify({ prompt: [{ type: "image", dataUrl: "data:image/png;base64,YQ==" }] }),
- )
- await Bun.sleep(0)
- await store.setItem("prompt", JSON.stringify({ prompt: [{ type: "text", content: "latest" }] }))
- migration.resolve()
- await older
-
- expect(documents.get("prompt")).toContain("latest")
-})
diff --git a/packages/cli/package.json b/packages/cli/package.json
index be5d853de0..46a372229b 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/cli",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"bin": {
diff --git a/packages/codemode/package.json b/packages/codemode/package.json
index 1641518483..e0c89ec26e 100644
--- a/packages/codemode/package.json
+++ b/packages/codemode/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/codemode",
- "version": "1.18.11",
+ "version": "1.18.10",
"description": "Effect-native confined code execution over schema-described tools",
"private": true,
"type": "module",
diff --git a/packages/console/app/package.json b/packages/console/app/package.json
index 5023021661..f27b89305f 100644
--- a/packages/console/app/package.json
+++ b/packages/console/app/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-app",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"scripts": {
diff --git a/packages/console/app/script/recover-lite-cancellations.ts b/packages/console/app/script/recover-lite-cancellations.ts
new file mode 100644
index 0000000000..ee65919ef5
--- /dev/null
+++ b/packages/console/app/script/recover-lite-cancellations.ts
@@ -0,0 +1,74 @@
+import type { Stripe } from "stripe"
+import { Billing } from "@opencode-ai/console-core/billing.js"
+import { BlackData } from "@opencode-ai/console-core/black.js"
+import { Database, and, inArray, isNotNull } from "@opencode-ai/console-core/drizzle/index.js"
+import { LiteData } from "@opencode-ai/console-core/lite.js"
+import { BillingTable } from "@opencode-ai/console-core/schema/billing.sql.js"
+import { subscriptionKind } from "../src/routes/stripe/lite-cancellation.js"
+
+const after = option("after")
+const before = option("before")
+if (!after || !before) throw new Error("Usage: recover-lite-cancellations.ts --after= --before= [--apply --expect=]")
+
+const start = new Date(after)
+const end = new Date(before)
+if (!Number.isFinite(start.getTime()) || !Number.isFinite(end.getTime())) throw new Error("Invalid recovery window")
+if (start >= end) throw new Error("Recovery window must end after it starts")
+if (end.getTime() - start.getTime() > 24 * 60 * 60 * 1000) throw new Error("Recovery window cannot exceed 24 hours")
+
+const subscriptionIDs: string[] = []
+for await (const event of Billing.stripe().events.list({
+ type: "customer.subscription.deleted",
+ created: {
+ gte: Math.floor(start.getTime() / 1000),
+ lt: Math.floor(end.getTime() / 1000),
+ },
+ limit: 100,
+})) {
+ const subscription = event.data.object as Stripe.Subscription
+ if (
+ subscriptionKind(subscription, {
+ liteProductID: LiteData.productID(),
+ blackProductID: BlackData.productID(),
+ }) !== "lite"
+ )
+ continue
+ subscriptionIDs.push(subscription.id)
+}
+
+const stale = subscriptionIDs.length
+ ? await Database.use((tx) =>
+ tx
+ .select({ subscriptionID: BillingTable.liteSubscriptionID })
+ .from(BillingTable)
+ .where(and(isNotNull(BillingTable.liteSubscriptionID), inArray(BillingTable.liteSubscriptionID, subscriptionIDs)))
+ .then((rows) => rows.map((row) => row.subscriptionID).filter((value): value is string => !!value)),
+ )
+ : []
+
+const apply = process.argv.includes("--apply")
+const expected = option("expect")
+if (!apply) {
+ console.log(JSON.stringify({ after: start.toISOString(), before: end.toISOString(), deletedGoSubscriptions: subscriptionIDs.length, staleEntitlements: stale.length, applied: false }))
+ process.exit(0)
+}
+if (!expected || Number(expected) !== stale.length) {
+ throw new Error(`Expected stale entitlement count must equal ${stale.length}`)
+}
+
+let cursor = 0
+await Promise.all(
+ Array.from({ length: Math.min(4, stale.length) }, async () => {
+ while (true) {
+ const index = cursor++
+ if (index >= stale.length) return
+ await Billing.unsubscribeLite({ subscriptionID: stale[index] })
+ }
+ }),
+)
+
+console.log(JSON.stringify({ after: start.toISOString(), before: end.toISOString(), deletedGoSubscriptions: subscriptionIDs.length, staleEntitlements: stale.length, applied: true }))
+
+function option(name: string) {
+ return process.argv.find((value) => value.startsWith(`--${name}=`))?.slice(name.length + 3)
+}
diff --git a/packages/console/app/src/i18n/ar.ts b/packages/console/app/src/i18n/ar.ts
index dd03a553f5..6b84df8e0e 100644
--- a/packages/console/app/src/i18n/ar.ts
+++ b/packages/console/app/src/i18n/ar.ts
@@ -347,7 +347,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"تُنشأ سجلات مراقبة إساءة الاستخدام لكل استخدام لميزات API، ويُحتفظ بها لمدة تصل إلى 30 يومًا.",
"go.faq.a5.learnMore": "اعرف المزيد",
- "go.faq.a5.deepseekRetention": "تُجدَّد اتفاقية ZDR شهريًا. الاتفاقية الحالية سارية حتى 31 أغسطس 2026.",
"go.faq.a5.beforeExceptions":
"تتم استضافة نماذج Go في الولايات المتحدة. يتبع المزودون سياسة عدم الاحتفاظ بالبيانات ولا يستخدمون بياناتك لتدريب النماذج، مع",
"go.faq.a5.exceptionsLink": "الاستثناءات التالية",
diff --git a/packages/console/app/src/i18n/br.ts b/packages/console/app/src/i18n/br.ts
index dac06753e9..10c171d0a8 100644
--- a/packages/console/app/src/i18n/br.ts
+++ b/packages/console/app/src/i18n/br.ts
@@ -354,8 +354,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Logs de monitoramento de abuso são gerados para todo uso de recursos da API e retidos por até 30 dias.",
"go.faq.a5.learnMore": "Saiba mais",
- "go.faq.a5.deepseekRetention":
- "O acordo de ZDR é renovado mensalmente. O acordo atual é válido até 31 de agosto de 2026.",
"go.faq.a5.beforeExceptions":
"Os modelos Go são hospedados nos EUA. Os provedores seguem uma política de retenção zero e não usam seus dados para treinamento de modelos, com as",
"go.faq.a5.exceptionsLink": "seguintes exceções",
diff --git a/packages/console/app/src/i18n/da.ts b/packages/console/app/src/i18n/da.ts
index 4e3d230f90..ab204d8aac 100644
--- a/packages/console/app/src/i18n/da.ts
+++ b/packages/console/app/src/i18n/da.ts
@@ -351,8 +351,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Logfiler til overvågning af misbrug genereres ved al brug af API-funktioner og opbevares i op til 30 dage.",
"go.faq.a5.learnMore": "Læs mere",
- "go.faq.a5.deepseekRetention":
- "ZDR-aftalen fornyes månedligt. Den nuværende aftale er gyldig til og med 31. august 2026.",
"go.faq.a5.beforeExceptions":
"Go-modeller hostes i USA. Udbydere følger en nulopbevaringspolitik og bruger ikke dine data til modeltræning, med de",
diff --git a/packages/console/app/src/i18n/de.ts b/packages/console/app/src/i18n/de.ts
index 61184358da..9a9f4dcbe1 100644
--- a/packages/console/app/src/i18n/de.ts
+++ b/packages/console/app/src/i18n/de.ts
@@ -353,8 +353,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Für die Nutzung aller API-Funktionen werden Protokolle zur Missbrauchsüberwachung erstellt und bis zu 30 Tage lang aufbewahrt.",
"go.faq.a5.learnMore": "Mehr erfahren",
- "go.faq.a5.deepseekRetention":
- "Die ZDR-Vereinbarung wird monatlich erneuert. Die aktuelle Vereinbarung gilt bis einschließlich 31. August 2026.",
"go.faq.a5.beforeExceptions":
"Go-Modelle werden in den USA gehostet. Anbieter verfolgen eine Zero-Retention-Politik und nutzen deine Daten nicht für das Training von Modellen, mit den",
"go.faq.a5.exceptionsLink": "folgenden Ausnahmen",
diff --git a/packages/console/app/src/i18n/en.ts b/packages/console/app/src/i18n/en.ts
index 813473c367..dcb2b4431d 100644
--- a/packages/console/app/src/i18n/en.ts
+++ b/packages/console/app/src/i18n/en.ts
@@ -348,8 +348,6 @@ export const dict = {
"ZDR disables important API features that depend on stored data, including the stateful Responses API, Files and Collections, and the Batch API.",
"go.faq.a5.gptRetention":
"Abuse monitoring logs are generated for all API feature usage and retained for up to 30 days.",
- "go.faq.a5.deepseekRetention":
- "ZDR agreement is renewed monthly. The current agreement is valid through August 31, 2026.",
"go.faq.a5.learnMore": "Learn more",
"go.faq.a5.beforeExceptions":
diff --git a/packages/console/app/src/i18n/es.ts b/packages/console/app/src/i18n/es.ts
index be5c24685c..506aa62950 100644
--- a/packages/console/app/src/i18n/es.ts
+++ b/packages/console/app/src/i18n/es.ts
@@ -354,8 +354,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Se generan registros de supervisión de abusos para todo el uso de funciones de la API y se conservan durante un máximo de 30 días.",
"go.faq.a5.learnMore": "Más información",
- "go.faq.a5.deepseekRetention":
- "El acuerdo de ZDR se renueva mensualmente. El acuerdo actual es válido hasta el 31 de agosto de 2026.",
"go.faq.a5.beforeExceptions":
"Los modelos de Go están alojados en EE. UU. Los proveedores siguen una política de retención cero y no utilizan tus datos para el entrenamiento de modelos, con las",
"go.faq.a5.exceptionsLink": "siguientes excepciones",
diff --git a/packages/console/app/src/i18n/fr.ts b/packages/console/app/src/i18n/fr.ts
index 37bf2d5eb3..f0238f2d08 100644
--- a/packages/console/app/src/i18n/fr.ts
+++ b/packages/console/app/src/i18n/fr.ts
@@ -355,8 +355,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Des journaux de surveillance des abus sont générés pour toute utilisation des fonctionnalités API et conservés pendant un maximum de 30 jours.",
"go.faq.a5.learnMore": "En savoir plus",
- "go.faq.a5.deepseekRetention":
- "L’accord ZDR est renouvelé chaque mois. L’accord actuel est valable jusqu’au 31 août 2026.",
"go.faq.a5.beforeExceptions":
"Les modèles Go sont hébergés aux États-Unis. Les fournisseurs suivent une politique de rétention zéro et n'utilisent pas vos données pour l'entraînement des modèles, avec les",
diff --git a/packages/console/app/src/i18n/it.ts b/packages/console/app/src/i18n/it.ts
index 501d012333..548d4d479f 100644
--- a/packages/console/app/src/i18n/it.ts
+++ b/packages/console/app/src/i18n/it.ts
@@ -350,8 +350,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"I log di monitoraggio degli abusi vengono generati per l'utilizzo di tutte le funzionalità API e conservati per un massimo di 30 giorni.",
"go.faq.a5.learnMore": "Scopri di più",
- "go.faq.a5.deepseekRetention":
- "L'accordo ZDR viene rinnovato mensilmente. L'accordo attuale è valido fino al 31 agosto 2026.",
"go.faq.a5.beforeExceptions":
"I modelli Go sono ospitati negli Stati Uniti. I provider seguono una policy di zero-retention e non usano i tuoi dati per l'addestramento dei modelli, con le",
"go.faq.a5.exceptionsLink": "seguenti eccezioni",
diff --git a/packages/console/app/src/i18n/ja.ts b/packages/console/app/src/i18n/ja.ts
index e8f8fa5661..fd4224d598 100644
--- a/packages/console/app/src/i18n/ja.ts
+++ b/packages/console/app/src/i18n/ja.ts
@@ -349,7 +349,6 @@ export const dict = {
"ZDRでは、保存データに依存する重要なAPI機能(ステートフルなResponses API、Files and Collections、Batch APIなど)が無効になります。",
"go.faq.a5.gptRetention": "不正使用監視ログはすべてのAPI機能の使用時に生成され、最大30日間保持されます。",
"go.faq.a5.learnMore": "詳しく見る",
- "go.faq.a5.deepseekRetention": "ZDR契約は毎月更新されます。現在の契約は2026年8月31日まで有効です。",
"go.faq.a5.beforeExceptions":
"Goのモデルは米国でホストされています。プロバイダーはゼロ保持ポリシーに従い、モデルのトレーニングにデータを使用しません(",
"go.faq.a5.exceptionsLink": "以下の例外",
diff --git a/packages/console/app/src/i18n/ko.ts b/packages/console/app/src/i18n/ko.ts
index ab76958985..9b6a0efbd4 100644
--- a/packages/console/app/src/i18n/ko.ts
+++ b/packages/console/app/src/i18n/ko.ts
@@ -345,7 +345,6 @@ export const dict = {
"ZDR은 저장된 데이터에 의존하는 중요한 API 기능(상태 저장형 Responses API, Files and Collections, Batch API 포함)을 비활성화합니다.",
"go.faq.a5.gptRetention": "모든 API 기능 사용에 대해 악용 모니터링 로그가 생성되며 최대 30일 동안 보존됩니다.",
"go.faq.a5.learnMore": "자세히 알아보기",
- "go.faq.a5.deepseekRetention": "ZDR 계약은 매월 갱신됩니다. 현재 계약은 2026년 8월 31일까지 유효합니다.",
"go.faq.a5.beforeExceptions":
"Go 모델은 미국에서 호스팅됩니다. 제공자들은 데이터 보존 금지 정책을 따르며 모델 학습에 데이터를 사용하지 않습니다. 단,",
"go.faq.a5.exceptionsLink": "다음 예외",
diff --git a/packages/console/app/src/i18n/no.ts b/packages/console/app/src/i18n/no.ts
index 5e7e025032..e3ff8db3cf 100644
--- a/packages/console/app/src/i18n/no.ts
+++ b/packages/console/app/src/i18n/no.ts
@@ -351,8 +351,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Logger for overvåking av misbruk genereres for all bruk av API-funksjoner og oppbevares i opptil 30 dager.",
"go.faq.a5.learnMore": "Les mer",
- "go.faq.a5.deepseekRetention":
- "ZDR-avtalen fornyes månedlig. Den gjeldende avtalen er gyldig til og med 31. august 2026.",
"go.faq.a5.beforeExceptions":
"Go-modeller hostes i USA. Leverandører følger en policy om null oppbevaring og bruker ikke dataene dine til modelltrening, med",
diff --git a/packages/console/app/src/i18n/pl.ts b/packages/console/app/src/i18n/pl.ts
index 2aa536cd82..874a90e5b0 100644
--- a/packages/console/app/src/i18n/pl.ts
+++ b/packages/console/app/src/i18n/pl.ts
@@ -352,7 +352,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Dzienniki monitorowania nadużyć są generowane dla każdego użycia funkcji API i przechowywane przez maksymalnie 30 dni.",
"go.faq.a5.learnMore": "Dowiedz się więcej",
- "go.faq.a5.deepseekRetention": "Umowa ZDR jest odnawiana co miesiąc. Obecna umowa obowiązuje do 31 sierpnia 2026 r.",
"go.faq.a5.beforeExceptions":
"Modele Go są hostowane w USA. Dostawcy stosują politykę zerowej retencji i nie używają Twoich danych do trenowania modeli, z",
diff --git a/packages/console/app/src/i18n/ru.ts b/packages/console/app/src/i18n/ru.ts
index 330713cd19..7cafbd687d 100644
--- a/packages/console/app/src/i18n/ru.ts
+++ b/packages/console/app/src/i18n/ru.ts
@@ -356,8 +356,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Журналы мониторинга злоупотреблений создаются при любом использовании функций API и хранятся до 30 дней.",
"go.faq.a5.learnMore": "Подробнее",
- "go.faq.a5.deepseekRetention":
- "Соглашение ZDR продлевается ежемесячно. Текущее соглашение действует до 31 августа 2026 года.",
"go.faq.a5.beforeExceptions":
"Модели Go размещены в США. Провайдеры следуют политике нулевого хранения и не используют ваши данные для обучения моделей, за",
diff --git a/packages/console/app/src/i18n/th.ts b/packages/console/app/src/i18n/th.ts
index d3ff91e97a..81ad9a9f37 100644
--- a/packages/console/app/src/i18n/th.ts
+++ b/packages/console/app/src/i18n/th.ts
@@ -348,7 +348,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"ระบบจะสร้างบันทึกการตรวจสอบการใช้งานในทางที่ผิดสำหรับการใช้งานฟีเจอร์ API ทั้งหมด และเก็บรักษาไว้นานสูงสุด 30 วัน",
"go.faq.a5.learnMore": "ดูข้อมูลเพิ่มเติม",
- "go.faq.a5.deepseekRetention": "ข้อตกลง ZDR จะต่ออายุทุกเดือน ข้อตกลงปัจจุบันมีผลใช้ถึงวันที่ 31 สิงหาคม 2026",
"go.faq.a5.beforeExceptions":
"โมเดล Go โฮสต์ในสหรัฐอเมริกา ผู้ให้บริการปฏิบัติตามนโยบายไม่เก็บรักษาข้อมูล (zero-retention policy) และไม่ใช้ข้อมูลของคุณสำหรับการฝึกโมเดล โดยมี",
diff --git a/packages/console/app/src/i18n/tr.ts b/packages/console/app/src/i18n/tr.ts
index 5d0d2819dd..701be9a5ae 100644
--- a/packages/console/app/src/i18n/tr.ts
+++ b/packages/console/app/src/i18n/tr.ts
@@ -354,8 +354,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Tüm API özelliklerinin kullanımı için kötüye kullanım izleme günlükleri oluşturulur ve 30 güne kadar saklanır.",
"go.faq.a5.learnMore": "Daha fazla bilgi",
- "go.faq.a5.deepseekRetention":
- "ZDR anlaşması aylık olarak yenilenir. Mevcut anlaşma 31 Ağustos 2026 tarihine kadar geçerlidir.",
"go.faq.a5.beforeExceptions":
"Go modelleri ABD'de barındırılmaktadır. Sağlayıcılar sıfır saklama politikası izler ve verilerinizi model eğitimi için kullanmaz; şu",
diff --git a/packages/console/app/src/i18n/uk.ts b/packages/console/app/src/i18n/uk.ts
index 48a0dbe787..0ee26f5f59 100644
--- a/packages/console/app/src/i18n/uk.ts
+++ b/packages/console/app/src/i18n/uk.ts
@@ -352,7 +352,6 @@ export const dict = {
"go.faq.a5.gptRetention":
"Журнали моніторингу зловживань створюються для всіх випадків використання функцій API та зберігаються до 30 днів.",
"go.faq.a5.learnMore": "Докладніше",
- "go.faq.a5.deepseekRetention": "Угода ZDR поновлюється щомісяця. Поточна угода дійсна до 31 серпня 2026 року.",
"go.faq.a5.beforeExceptions":
"Моделі Go розміщені в США. Провайдери дотримуються політики нульового зберігання та не використовують ваші дані для навчання моделей, за",
diff --git a/packages/console/app/src/i18n/zh.ts b/packages/console/app/src/i18n/zh.ts
index 78f2081aeb..d4a59900fc 100644
--- a/packages/console/app/src/i18n/zh.ts
+++ b/packages/console/app/src/i18n/zh.ts
@@ -333,7 +333,6 @@ export const dict = {
"ZDR 会禁用依赖所存储数据的重要 API 功能,包括有状态的 Responses API、Files and Collections 和 Batch API。",
"go.faq.a5.gptRetention": "所有 API 功能的使用都会生成滥用监控日志,并最多保留 30 天。",
"go.faq.a5.learnMore": "了解更多",
- "go.faq.a5.deepseekRetention": "ZDR 协议每月续签。当前协议有效期至 2026 年 8 月 31 日。",
"go.faq.a5.beforeExceptions": "Go 模型托管在美国。提供商遵循零留存政策,不使用您的数据进行模型训练,",
"go.faq.a5.exceptionsLink": "以下例外情况除外",
"go.faq.q6": "我可以充值余额吗?",
diff --git a/packages/console/app/src/i18n/zht.ts b/packages/console/app/src/i18n/zht.ts
index 190a927d3f..635ad91d2f 100644
--- a/packages/console/app/src/i18n/zht.ts
+++ b/packages/console/app/src/i18n/zht.ts
@@ -333,7 +333,6 @@ export const dict = {
"ZDR 會停用依賴儲存資料的重要 API 功能,包括具狀態的 Responses API、Files and Collections 與 Batch API。",
"go.faq.a5.gptRetention": "所有 API 功能的使用都會產生濫用監控日誌,並保留最多 30 天。",
"go.faq.a5.learnMore": "了解更多",
- "go.faq.a5.deepseekRetention": "ZDR 協議每月續簽。目前的協議有效至 2026 年 8 月 31 日。",
"go.faq.a5.beforeExceptions": "Go 模型託管在美國。供應商遵循零留存政策,不會將你的資料用於模型訓練,但有",
"go.faq.a5.exceptionsLink": "以下例外",
"go.faq.q6": "我可以儲值額度嗎?",
diff --git a/packages/console/app/src/routes/go/index.tsx b/packages/console/app/src/routes/go/index.tsx
index 17c78f214d..710650d4dc 100644
--- a/packages/console/app/src/routes/go/index.tsx
+++ b/packages/console/app/src/routes/go/index.tsx
@@ -32,14 +32,13 @@ const models = [
{ name: "Kimi K2.6", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "MiMo-V2.5-Pro", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "MiMo-V2.5", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
- { name: "Qwen3.8 Max", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "Qwen3.7 Max", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "Qwen3.7 Plus", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "Qwen3.6 Plus", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "MiniMax M3", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "MiniMax M2.7", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
{ name: "DeepSeek V4 Pro", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
- { name: "DeepSeek V4 Flash", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
+ { name: "DeepSeek V4 Flash", training: "go.faq.a5.used", retention: "go.faq.a5.noAgreement" },
{ name: "Hy3", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" },
] as const
@@ -68,7 +67,6 @@ function LimitsGraph(props: { href: string }) {
const graph = [
{ id: "grok-4.5", name: "Grok 4.5", req: 120, d: "50ms" },
{ id: "kimi-k3", name: "Kimi K3", req: 110, d: "75ms" },
- { id: "qwen3.8-max", name: "Qwen3.8 Max", req: 160, d: "90ms" },
{ id: "glm-5.2", name: "GLM-5.2", req: 880, d: "100ms" },
{ id: "minimax-m3", name: "MiniMax M3", req: 3200, d: "210ms" },
{ id: "deepseek-v4-pro", name: "DeepSeek V4 Pro", req: 3450, d: "270ms" },
@@ -507,9 +505,6 @@ export default function Home() {
.
-
- DeepSeek V4 Flash: {i18n.t("go.faq.a5.deepseekRetention")}
-
diff --git a/packages/console/app/src/routes/stripe/lite-cancellation.ts b/packages/console/app/src/routes/stripe/lite-cancellation.ts
new file mode 100644
index 0000000000..9ade01f48e
--- /dev/null
+++ b/packages/console/app/src/routes/stripe/lite-cancellation.ts
@@ -0,0 +1,50 @@
+type SubscriptionEventType = "customer.subscription.deleted" | "customer.subscription.updated"
+
+type Subscription = {
+ id: string
+ status: string
+ metadata: Record
+ items: {
+ data: Array<{
+ price: {
+ product: string | { id: string }
+ }
+ }>
+ }
+}
+
+type Actions = {
+ liteProductID: string
+ blackProductID: string
+ unsubscribeLite(subscriptionID: string): Promise
+ unsubscribeBlack(subscriptionID: string): Promise
+}
+
+export function subscriptionKind(
+ subscription: Subscription,
+ products: Pick,
+) {
+ const product = subscription.items.data[0]?.price.product
+ const productID = typeof product === "string" ? product : product?.id
+ if (subscription.metadata.type === "lite" || productID === products.liteProductID) return "lite"
+ if (productID === products.blackProductID) return "black"
+}
+
+export async function handleSubscriptionCancellation(
+ type: SubscriptionEventType,
+ subscription: Subscription,
+ actions: Actions,
+) {
+ if (type === "customer.subscription.updated" && subscription.status !== "incomplete_expired") return false
+
+ const kind = subscriptionKind(subscription, actions)
+ if (kind === "lite") {
+ await actions.unsubscribeLite(subscription.id)
+ return true
+ }
+ if (kind === "black") {
+ await actions.unsubscribeBlack(subscription.id)
+ return true
+ }
+ throw new Error("Unknown subscription product")
+}
diff --git a/packages/console/app/src/routes/stripe/webhook.ts b/packages/console/app/src/routes/stripe/webhook.ts
index e1e4e6cbd3..edb076f181 100644
--- a/packages/console/app/src/routes/stripe/webhook.ts
+++ b/packages/console/app/src/routes/stripe/webhook.ts
@@ -10,6 +10,7 @@ import { Resource } from "@opencode-ai/console-resource"
import { LiteData } from "@opencode-ai/console-core/lite.js"
import { BlackData } from "@opencode-ai/console-core/black.js"
import { Referral } from "@opencode-ai/console-core/referral.js"
+import { handleSubscriptionCancellation } from "./lite-cancellation.js"
export async function POST(input: APIEvent) {
const body = await Billing.stripe().webhooks.constructEventAsync(
@@ -184,27 +185,13 @@ export async function POST(input: APIEvent) {
})
}
}
- if (body.type === "customer.subscription.updated" && body.data.object.status === "incomplete_expired") {
- const subscriptionID = body.data.object.id
- if (!subscriptionID) throw new Error("Subscription ID not found")
-
- const productID = body.data.object.items.data[0].price.product as string
- if (productID === LiteData.productID()) {
- await Billing.unsubscribeLite({ subscriptionID })
- } else if (productID === BlackData.productID()) {
- await Billing.unsubscribeBlack({ subscriptionID })
- }
- }
- if (body.type === "customer.subscription.deleted") {
- const subscriptionID = body.data.object.id
- if (!subscriptionID) throw new Error("Subscription ID not found")
-
- const productID = body.data.object.items.data[0].price.product as string
- if (productID === LiteData.productID()) {
- await Billing.unsubscribeLite({ subscriptionID })
- } else if (productID === BlackData.productID()) {
- await Billing.unsubscribeBlack({ subscriptionID })
- }
+ if (body.type === "customer.subscription.updated" || body.type === "customer.subscription.deleted") {
+ await handleSubscriptionCancellation(body.type, body.data.object, {
+ liteProductID: LiteData.productID(),
+ blackProductID: BlackData.productID(),
+ unsubscribeLite: (subscriptionID) => Billing.unsubscribeLite({ subscriptionID }),
+ unsubscribeBlack: (subscriptionID) => Billing.unsubscribeBlack({ subscriptionID }),
+ })
}
if (body.type === "invoice.payment_succeeded") {
if (
diff --git a/packages/console/app/src/routes/workspace/[id]/go/lite-section.tsx b/packages/console/app/src/routes/workspace/[id]/go/lite-section.tsx
index da1b053a35..331c13e147 100644
--- a/packages/console/app/src/routes/workspace/[id]/go/lite-section.tsx
+++ b/packages/console/app/src/routes/workspace/[id]/go/lite-section.tsx
@@ -313,7 +313,6 @@ export function LiteSection(props: { lite: LiteSubscription | undefined }) {
Kimi K2.6
MiniMax M3
MiniMax M2.7
- Qwen3.8 Max
Qwen3.7 Max
Qwen3.7 Plus
Qwen3.6 Plus
diff --git a/packages/console/app/src/routes/zen/util/provider/google.ts b/packages/console/app/src/routes/zen/util/provider/google.ts
index 1bc2ce1f21..404657d443 100644
--- a/packages/console/app/src/routes/zen/util/provider/google.ts
+++ b/packages/console/app/src/routes/zen/util/provider/google.ts
@@ -65,7 +65,7 @@ export const googleHelper: ProviderHelper = ({ providerModel }) => ({
const cacheReadTokens = usage.cachedContentTokenCount ?? 0
return {
inputTokens: inputTokens - cacheReadTokens,
- outputTokens: outputTokens + reasoningTokens,
+ outputTokens,
reasoningTokens,
cacheReadTokens,
cacheWrite5mTokens: undefined,
diff --git a/packages/console/app/test/liteCancellation.test.ts b/packages/console/app/test/liteCancellation.test.ts
new file mode 100644
index 0000000000..b636df51b7
--- /dev/null
+++ b/packages/console/app/test/liteCancellation.test.ts
@@ -0,0 +1,115 @@
+import { expect, test } from "bun:test"
+import { handleSubscriptionCancellation } from "../src/routes/stripe/lite-cancellation"
+
+test("revokes a deleted Go subscription from metadata even when the product ID changed", async () => {
+ const revoked: string[] = []
+
+ expect(
+ await handleSubscriptionCancellation(
+ "customer.subscription.deleted",
+ {
+ id: "sub_go",
+ status: "canceled",
+ metadata: { type: "lite" },
+ items: { data: [{ price: { product: "prod_old" } }] },
+ },
+ {
+ liteProductID: "prod_current",
+ blackProductID: "prod_black",
+ unsubscribeLite: async (subscriptionID) => revoked.push(subscriptionID),
+ unsubscribeBlack: async () => {},
+ },
+ ),
+ ).toBe(true)
+ expect(revoked).toEqual(["sub_go"])
+})
+
+test("ignores active subscription updates", async () => {
+ expect(
+ await handleSubscriptionCancellation(
+ "customer.subscription.updated",
+ {
+ id: "sub_go",
+ status: "active",
+ metadata: { type: "lite" },
+ items: { data: [{ price: { product: "prod_go" } }] },
+ },
+ {
+ liteProductID: "prod_go",
+ blackProductID: "prod_black",
+ unsubscribeLite: async () => {
+ throw new Error("unexpected unsubscribe")
+ },
+ unsubscribeBlack: async () => {
+ throw new Error("unexpected unsubscribe")
+ },
+ },
+ ),
+ ).toBe(false)
+})
+
+test("revokes an incomplete expired Go subscription update", async () => {
+ const revoked: string[] = []
+
+ expect(
+ await handleSubscriptionCancellation(
+ "customer.subscription.updated",
+ {
+ id: "sub_go",
+ status: "incomplete_expired",
+ metadata: { type: "lite" },
+ items: { data: [{ price: { product: "prod_go" } }] },
+ },
+ {
+ liteProductID: "prod_go",
+ blackProductID: "prod_black",
+ unsubscribeLite: async (subscriptionID) => revoked.push(subscriptionID),
+ unsubscribeBlack: async () => {},
+ },
+ ),
+ ).toBe(true)
+ expect(revoked).toEqual(["sub_go"])
+})
+
+test("preserves Black cancellation handling", async () => {
+ const revoked: string[] = []
+
+ expect(
+ await handleSubscriptionCancellation(
+ "customer.subscription.deleted",
+ {
+ id: "sub_black",
+ status: "canceled",
+ metadata: {},
+ items: { data: [{ price: { product: "prod_black" } }] },
+ },
+ {
+ liteProductID: "prod_go",
+ blackProductID: "prod_black",
+ unsubscribeLite: async () => {},
+ unsubscribeBlack: async (subscriptionID) => revoked.push(subscriptionID),
+ },
+ ),
+ ).toBe(true)
+ expect(revoked).toEqual(["sub_black"])
+})
+
+test("rejects deleted subscriptions that cannot be classified", async () => {
+ expect(
+ handleSubscriptionCancellation(
+ "customer.subscription.deleted",
+ {
+ id: "sub_unknown",
+ status: "canceled",
+ metadata: {},
+ items: { data: [{ price: { product: "prod_unknown" } }] },
+ },
+ {
+ liteProductID: "prod_go",
+ blackProductID: "prod_black",
+ unsubscribeLite: async () => {},
+ unsubscribeBlack: async () => {},
+ },
+ ),
+ ).rejects.toThrow("Unknown subscription product")
+})
diff --git a/packages/console/core/migrations/20260803084635_married_misty_knight/migration.sql b/packages/console/core/migrations/20260803084635_married_misty_knight/migration.sql
deleted file mode 100644
index 2ef8df67a6..0000000000
--- a/packages/console/core/migrations/20260803084635_married_misty_knight/migration.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-CREATE UNIQUE INDEX `global_lite_subscription_id` ON `billing` (`lite_subscription_id`);--> statement-breakpoint
-CREATE INDEX `referral_id` ON `referral_reward` (`referral_id`);
\ No newline at end of file
diff --git a/packages/console/core/migrations/20260803084635_married_misty_knight/snapshot.json b/packages/console/core/migrations/20260803084635_married_misty_knight/snapshot.json
deleted file mode 100644
index 239f3266f2..0000000000
--- a/packages/console/core/migrations/20260803084635_married_misty_knight/snapshot.json
+++ /dev/null
@@ -1,3167 +0,0 @@
-{
- "version": "6",
- "dialect": "mysql",
- "id": "2752a0ba-95b5-492a-83fd-3dfe7fa77734",
- "prevIds": ["c143f6ef-07b8-401f-8281-462bf49b6501"],
- "ddl": [
- {
- "name": "account",
- "entityType": "tables"
- },
- {
- "name": "auth",
- "entityType": "tables"
- },
- {
- "name": "benchmark",
- "entityType": "tables"
- },
- {
- "name": "billing",
- "entityType": "tables"
- },
- {
- "name": "coupon",
- "entityType": "tables"
- },
- {
- "name": "lite",
- "entityType": "tables"
- },
- {
- "name": "payment",
- "entityType": "tables"
- },
- {
- "name": "subscription",
- "entityType": "tables"
- },
- {
- "name": "usage",
- "entityType": "tables"
- },
- {
- "name": "ip_rate_limit",
- "entityType": "tables"
- },
- {
- "name": "ip",
- "entityType": "tables"
- },
- {
- "name": "key_rate_limit",
- "entityType": "tables"
- },
- {
- "name": "model_sticky_provider",
- "entityType": "tables"
- },
- {
- "name": "model_tpm_rate_limit",
- "entityType": "tables"
- },
- {
- "name": "model_tps_rate_limit",
- "entityType": "tables"
- },
- {
- "name": "key",
- "entityType": "tables"
- },
- {
- "name": "model",
- "entityType": "tables"
- },
- {
- "name": "provider",
- "entityType": "tables"
- },
- {
- "name": "referral_code",
- "entityType": "tables"
- },
- {
- "name": "referral_reward",
- "entityType": "tables"
- },
- {
- "name": "referral",
- "entityType": "tables"
- },
- {
- "name": "user",
- "entityType": "tables"
- },
- {
- "name": "workspace",
- "entityType": "tables"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "account"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "account"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "account"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "account"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "enum('email','github','google')",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "provider",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "subject",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "account_id",
- "entityType": "columns",
- "table": "auth"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "varchar(64)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "model",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "varchar(64)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "agent",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "mediumtext",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "result",
- "entityType": "columns",
- "table": "benchmark"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "customer_id",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "payment_method_id",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(32)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "payment_method_type",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(4)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "payment_method_last4",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "bigint",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "balance",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "monthly_limit",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "monthly_usage",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_monthly_usage_updated",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "boolean",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "reload",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "reload_trigger",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "reload_amount",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "reload_error",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_reload_error",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_reload_locked_till",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "json",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "subscription",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(28)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "subscription_id",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "enum('20','100','200')",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "subscription_plan",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_subscription_booked",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_subscription_selected",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(28)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "lite_subscription_id",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "json",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "lite",
- "entityType": "columns",
- "table": "billing"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "email",
- "entityType": "columns",
- "table": "coupon"
- },
- {
- "type": "enum('BUILDATHON','GO1MONTH50','GOFREEMONTH','GO3MONTHS100','GO6MONTHS100','GO12MONTHS100')",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "type",
- "entityType": "columns",
- "table": "coupon"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_redeemed",
- "entityType": "columns",
- "table": "coupon"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "user_id",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "rolling_usage",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "weekly_usage",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "monthly_usage",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_rolling_updated",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_weekly_updated",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_monthly_updated",
- "entityType": "columns",
- "table": "lite"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "customer_id",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "invoice_id",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "payment_id",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "bigint",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "amount",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_refunded",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "json",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "enrichment",
- "entityType": "columns",
- "table": "payment"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "user_id",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "rolling_usage",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "fixed_usage",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_rolling_updated",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_fixed_updated",
- "entityType": "columns",
- "table": "subscription"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "model",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "provider",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "input_tokens",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "output_tokens",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "reasoning_tokens",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "cache_read_tokens",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "cache_write_5m_tokens",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "cache_write_1h_tokens",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "bigint",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "cost",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "varchar(30)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "key_id",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "varchar(30)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "session_id",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "json",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "enrichment",
- "entityType": "columns",
- "table": "usage"
- },
- {
- "type": "varchar(45)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "ip",
- "entityType": "columns",
- "table": "ip_rate_limit"
- },
- {
- "type": "varchar(10)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "interval",
- "entityType": "columns",
- "table": "ip_rate_limit"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "count",
- "entityType": "columns",
- "table": "ip_rate_limit"
- },
- {
- "type": "varchar(45)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "ip",
- "entityType": "columns",
- "table": "ip"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "ip"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "ip"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "ip"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "usage",
- "entityType": "columns",
- "table": "ip"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "key",
- "entityType": "columns",
- "table": "key_rate_limit"
- },
- {
- "type": "varchar(40)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "interval",
- "entityType": "columns",
- "table": "key_rate_limit"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "count",
- "entityType": "columns",
- "table": "key_rate_limit"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "model_sticky_provider"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "model_sticky_provider"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "model_sticky_provider"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "model_sticky_provider"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "provider_id",
- "entityType": "columns",
- "table": "model_sticky_provider"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "model_tpm_rate_limit"
- },
- {
- "type": "bigint",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "interval",
- "entityType": "columns",
- "table": "model_tpm_rate_limit"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "count",
- "entityType": "columns",
- "table": "model_tpm_rate_limit"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "model_tps_rate_limit"
- },
- {
- "type": "bigint",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "interval",
- "entityType": "columns",
- "table": "model_tps_rate_limit"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "qualify",
- "entityType": "columns",
- "table": "model_tps_rate_limit"
- },
- {
- "type": "int",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "unqualify",
- "entityType": "columns",
- "table": "model_tps_rate_limit"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "name",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "key",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "user_id",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_used",
- "entityType": "columns",
- "table": "key"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "model"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "model"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "model"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "model"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "model"
- },
- {
- "type": "varchar(64)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "model",
- "entityType": "columns",
- "table": "model"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "varchar(64)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "provider",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "text",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "credentials",
- "entityType": "columns",
- "table": "provider"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "referral_code"
- },
- {
- "type": "varchar(10)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "code",
- "entityType": "columns",
- "table": "referral_code"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "referral_code"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "referral_code"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "referral_code"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "referral_id",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "bigint",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "amount",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_applied",
- "entityType": "columns",
- "table": "referral_reward"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "referral"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "referral"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "referral"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "referral"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "referral"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "invitee_account_id",
- "entityType": "columns",
- "table": "referral"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "workspace_id",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "varchar(30)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "account_id",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "email",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "name",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_seen",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "color",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "enum('admin','member')",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "role",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "int",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "monthly_limit",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "bigint",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "monthly_usage",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_monthly_usage_updated",
- "entityType": "columns",
- "table": "user"
- },
- {
- "type": "varchar(30)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "id",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "varchar(255)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "slug",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "varchar(255)",
- "notNull": true,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "name",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "json",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "region",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "boolean",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "is_blocked",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "boolean",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "is_flagged_by_anthropic",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "boolean",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "is_flagged_by_openai",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(now())",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_created",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "timestamp(3)",
- "notNull": true,
- "autoIncrement": false,
- "default": "(CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3))",
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_updated",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "type": "timestamp(3)",
- "notNull": false,
- "autoIncrement": false,
- "default": null,
- "onUpdateNow": false,
- "onUpdateNowFsp": null,
- "charSet": null,
- "collation": null,
- "generated": null,
- "name": "time_deleted",
- "entityType": "columns",
- "table": "workspace"
- },
- {
- "columns": ["id"],
- "name": "PRIMARY",
- "table": "account",
- "entityType": "pks"
- },
- {
- "columns": ["id"],
- "name": "PRIMARY",
- "table": "auth",
- "entityType": "pks"
- },
- {
- "columns": ["id"],
- "name": "PRIMARY",
- "table": "benchmark",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "billing",
- "entityType": "pks"
- },
- {
- "columns": ["email", "type"],
- "name": "PRIMARY",
- "table": "coupon",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "lite",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "payment",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "subscription",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "usage",
- "entityType": "pks"
- },
- {
- "columns": ["ip", "interval"],
- "name": "PRIMARY",
- "table": "ip_rate_limit",
- "entityType": "pks"
- },
- {
- "columns": ["ip"],
- "name": "PRIMARY",
- "table": "ip",
- "entityType": "pks"
- },
- {
- "columns": ["key", "interval"],
- "name": "PRIMARY",
- "table": "key_rate_limit",
- "entityType": "pks"
- },
- {
- "columns": ["id"],
- "name": "PRIMARY",
- "table": "model_sticky_provider",
- "entityType": "pks"
- },
- {
- "columns": ["id", "interval"],
- "name": "PRIMARY",
- "table": "model_tpm_rate_limit",
- "entityType": "pks"
- },
- {
- "columns": ["id", "interval"],
- "name": "PRIMARY",
- "table": "model_tps_rate_limit",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "key",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "model",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "provider",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id"],
- "name": "PRIMARY",
- "table": "referral_code",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "referral_id"],
- "name": "PRIMARY",
- "table": "referral_reward",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "referral",
- "entityType": "pks"
- },
- {
- "columns": ["workspace_id", "id"],
- "name": "PRIMARY",
- "table": "user",
- "entityType": "pks"
- },
- {
- "columns": ["id"],
- "name": "PRIMARY",
- "table": "workspace",
- "entityType": "pks"
- },
- {
- "columns": [
- {
- "value": "provider",
- "isExpression": false
- },
- {
- "value": "subject",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "provider",
- "entityType": "indexes",
- "table": "auth"
- },
- {
- "columns": [
- {
- "value": "account_id",
- "isExpression": false
- }
- ],
- "isUnique": false,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "account_id",
- "entityType": "indexes",
- "table": "auth"
- },
- {
- "columns": [
- {
- "value": "time_created",
- "isExpression": false
- }
- ],
- "isUnique": false,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "time_created",
- "entityType": "indexes",
- "table": "benchmark"
- },
- {
- "columns": [
- {
- "value": "customer_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "global_customer_id",
- "entityType": "indexes",
- "table": "billing"
- },
- {
- "columns": [
- {
- "value": "subscription_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "global_subscription_id",
- "entityType": "indexes",
- "table": "billing"
- },
- {
- "columns": [
- {
- "value": "lite_subscription_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "global_lite_subscription_id",
- "entityType": "indexes",
- "table": "billing"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "user_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "workspace_user_id",
- "entityType": "indexes",
- "table": "lite"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "user_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "workspace_user_id",
- "entityType": "indexes",
- "table": "subscription"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "time_created",
- "isExpression": false
- }
- ],
- "isUnique": false,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "usage_time_created",
- "entityType": "indexes",
- "table": "usage"
- },
- {
- "columns": [
- {
- "value": "key",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "global_key",
- "entityType": "indexes",
- "table": "key"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "model",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "model_workspace_model",
- "entityType": "indexes",
- "table": "model"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "provider",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "workspace_provider",
- "entityType": "indexes",
- "table": "provider"
- },
- {
- "columns": [
- {
- "value": "code",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "code",
- "entityType": "indexes",
- "table": "referral_code"
- },
- {
- "columns": [
- {
- "value": "referral_id",
- "isExpression": false
- }
- ],
- "isUnique": false,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "referral_id",
- "entityType": "indexes",
- "table": "referral_reward"
- },
- {
- "columns": [
- {
- "value": "invitee_account_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "invitee_account_id",
- "entityType": "indexes",
- "table": "referral"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "account_id",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "user_account_id",
- "entityType": "indexes",
- "table": "user"
- },
- {
- "columns": [
- {
- "value": "workspace_id",
- "isExpression": false
- },
- {
- "value": "email",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "user_email",
- "entityType": "indexes",
- "table": "user"
- },
- {
- "columns": [
- {
- "value": "account_id",
- "isExpression": false
- }
- ],
- "isUnique": false,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "global_account_id",
- "entityType": "indexes",
- "table": "user"
- },
- {
- "columns": [
- {
- "value": "email",
- "isExpression": false
- }
- ],
- "isUnique": false,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "global_email",
- "entityType": "indexes",
- "table": "user"
- },
- {
- "columns": [
- {
- "value": "slug",
- "isExpression": false
- }
- ],
- "isUnique": true,
- "using": null,
- "algorithm": null,
- "lock": null,
- "nameExplicit": true,
- "name": "slug",
- "entityType": "indexes",
- "table": "workspace"
- }
- ],
- "renames": []
-}
diff --git a/packages/console/core/package.json b/packages/console/core/package.json
index ea543f40db..63ba0a50f2 100644
--- a/packages/console/core/package.json
+++ b/packages/console/core/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/console-core",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/console/core/src/referral.ts b/packages/console/core/src/referral.ts
index 7fac9e1b98..7d683f8d88 100644
--- a/packages/console/core/src/referral.ts
+++ b/packages/console/core/src/referral.ts
@@ -59,7 +59,30 @@ export namespace Referral {
const accountID = Actor.account()
const code = await ensureCode(workspaceID)
const rows = await Database.use(async (tx) => {
- const [invites, inviteeReferral] = await Promise.all([
+ const [rewards, invites, inviteeReferral, inviteeRewards] = await Promise.all([
+ tx
+ .select({
+ referralID: ReferralRewardTable.referralID,
+ workspaceID: ReferralRewardTable.workspaceID,
+ referralWorkspaceID: ReferralTable.workspaceID,
+ inviteeEmail: AuthTable.subject,
+ amount: ReferralRewardTable.amount,
+ timeCreated: ReferralRewardTable.timeCreated,
+ timeApplied: ReferralRewardTable.timeApplied,
+ })
+ .from(ReferralRewardTable)
+ .innerJoin(ReferralTable, eq(ReferralTable.id, ReferralRewardTable.referralID))
+ .innerJoin(
+ AuthTable,
+ and(eq(AuthTable.accountID, ReferralTable.inviteeAccountID), eq(AuthTable.provider, "email")),
+ )
+ .where(
+ and(
+ eq(ReferralRewardTable.workspaceID, workspaceID),
+ isNull(ReferralRewardTable.timeDeleted),
+ isNull(ReferralTable.timeDeleted),
+ ),
+ ),
tx
.select({ id: ReferralTable.id, inviteeEmail: AuthTable.subject, timeCreated: ReferralTable.timeCreated })
.from(ReferralTable)
@@ -83,20 +106,19 @@ export namespace Referral {
.where(and(eq(ReferralTable.inviteeAccountID, accountID), isNull(ReferralTable.timeDeleted)))
.orderBy(asc(UserTable.timeCreated))
.then((rows) => rows.find((row) => row.inviterEmail) ?? rows[0]),
+ tx
+ .select({ referralID: ReferralRewardTable.referralID })
+ .from(ReferralRewardTable)
+ .innerJoin(ReferralTable, eq(ReferralTable.id, ReferralRewardTable.referralID))
+ .where(
+ and(
+ eq(ReferralTable.inviteeAccountID, accountID),
+ isNull(ReferralRewardTable.timeDeleted),
+ isNull(ReferralTable.timeDeleted),
+ ),
+ ),
])
- // Hide reward history until the referral_id index can be deployed and this lookup restored.
- const rewards: {
- referralID: string
- workspaceID: string
- referralWorkspaceID: string
- inviteeEmail: string
- amount: number
- timeCreated: Date
- timeApplied: Date | null
- }[] = []
- // Hide pending invitee rewards until the referral_id index can be deployed and this lookup restored.
- const inviteeRewards = inviteeReferral ? [{ referralID: inviteeReferral.id }] : []
return { inviteeReferral, inviteeRewards, invites, rewards }
})
diff --git a/packages/console/core/src/schema/billing.sql.ts b/packages/console/core/src/schema/billing.sql.ts
index b177858f36..915646cf3d 100644
--- a/packages/console/core/src/schema/billing.sql.ts
+++ b/packages/console/core/src/schema/billing.sql.ts
@@ -53,7 +53,6 @@ export const BillingTable = mysqlTable(
...workspaceIndexes(table),
uniqueIndex("global_customer_id").on(table.customerID),
uniqueIndex("global_subscription_id").on(table.subscriptionID),
- uniqueIndex("global_lite_subscription_id").on(table.liteSubscriptionID),
],
)
diff --git a/packages/console/core/src/schema/referral.sql.ts b/packages/console/core/src/schema/referral.sql.ts
index be2499ee11..9850c92457 100644
--- a/packages/console/core/src/schema/referral.sql.ts
+++ b/packages/console/core/src/schema/referral.sql.ts
@@ -1,4 +1,4 @@
-import { bigint, index, mysqlTable, primaryKey, uniqueIndex, varchar } from "drizzle-orm/mysql-core"
+import { bigint, mysqlTable, primaryKey, uniqueIndex, varchar } from "drizzle-orm/mysql-core"
import { timestamps, ulid, utc, workspaceColumns } from "../drizzle/types"
import { workspaceIndexes } from "./workspace.sql"
@@ -31,8 +31,5 @@ export const ReferralRewardTable = mysqlTable(
amount: bigint("amount", { mode: "number" }).notNull(),
timeApplied: utc("time_applied"),
},
- (table) => [
- primaryKey({ columns: [table.workspaceID, table.referralID] }),
- index("referral_id").on(table.referralID),
- ],
+ (table) => [primaryKey({ columns: [table.workspaceID, table.referralID] })],
)
diff --git a/packages/console/function/package.json b/packages/console/function/package.json
index 4aa9b01170..52581a8c93 100644
--- a/packages/console/function/package.json
+++ b/packages/console/function/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-function",
- "version": "1.18.11",
+ "version": "1.18.10",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
diff --git a/packages/console/mail/package.json b/packages/console/mail/package.json
index 071ca199d6..f54268c9c8 100644
--- a/packages/console/mail/package.json
+++ b/packages/console/mail/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-mail",
- "version": "1.18.11",
+ "version": "1.18.10",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
diff --git a/packages/console/support/package.json b/packages/console/support/package.json
index a69bbe4268..6b6a65b6e6 100644
--- a/packages/console/support/package.json
+++ b/packages/console/support/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/console-support",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"scripts": {
diff --git a/packages/core/package.json b/packages/core/package.json
index babaec7d6c..a8a5041e73 100644
--- a/packages/core/package.json
+++ b/packages/core/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.18.11",
+ "version": "1.18.10",
"name": "@opencode-ai/core",
"type": "module",
"license": "MIT",
diff --git a/packages/desktop/package.json b/packages/desktop/package.json
index 6776591b3e..a407d3d192 100644
--- a/packages/desktop/package.json
+++ b/packages/desktop/package.json
@@ -1,7 +1,7 @@
{
"name": "@opencode-ai/desktop",
"private": true,
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"homepage": "https://opencode.ai",
@@ -30,8 +30,7 @@
"electron-log": "^5",
"electron-store": "11.0.2",
"electron-updater": "6.8.9",
- "electron-window-state": "^5.0.3",
- "drizzle-orm": "catalog:"
+ "electron-window-state": "^5.0.3"
},
"devDependencies": {
"@actions/artifact": "4.0.0",
diff --git a/packages/desktop/src/main/draft-store.test.ts b/packages/desktop/src/main/draft-store.test.ts
deleted file mode 100644
index 95d4e7aa80..0000000000
--- a/packages/desktop/src/main/draft-store.test.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { expect, test } from "bun:test"
-import { createDesktopDraftStore } from "./draft-store"
-
-test("flushes the latest buffered draft and stores blobs", () => {
- const store = createDesktopDraftStore(":memory:")
- store.set("prompt", "first")
- store.set("prompt", "latest")
- expect(store.get("prompt")).toBe("latest")
- store.flush()
- expect(store.get("prompt")).toBe("latest")
-
- const bytes = new TextEncoder().encode("image")
- const id = store.putBlob(bytes)
- expect(store.getBlob(id)).toEqual(bytes)
- store.close()
-})
diff --git a/packages/desktop/src/main/draft-store.ts b/packages/desktop/src/main/draft-store.ts
deleted file mode 100644
index 839eff26af..0000000000
--- a/packages/desktop/src/main/draft-store.ts
+++ /dev/null
@@ -1,82 +0,0 @@
-import { createHash } from "node:crypto"
-import { DatabaseSync } from "node:sqlite"
-import { eq } from "drizzle-orm"
-import { drizzle } from "drizzle-orm/node-sqlite"
-import { blob, sqliteTable, text } from "drizzle-orm/sqlite-core"
-
-const documents = sqliteTable("document", {
- key: text().primaryKey(),
- value: text().notNull(),
-})
-const blobs = sqliteTable("blob", {
- id: text().primaryKey(),
- data: blob({ mode: "buffer" }).notNull(),
-})
-
-export function createDesktopDraftStore(filename: string) {
- const native = new DatabaseSync(filename)
- native.exec(
- "PRAGMA journal_mode=WAL; CREATE TABLE IF NOT EXISTS document (key TEXT PRIMARY KEY, value TEXT NOT NULL); CREATE TABLE IF NOT EXISTS blob (id TEXT PRIMARY KEY, data BLOB NOT NULL);",
- )
- const db = drizzle({ client: native })
- const used = new Set()
- db.select({ value: documents.value })
- .from(documents)
- .all()
- .forEach(({ value }) =>
- JSON.parse(value, (_key, item) => {
- if (item?.blob && typeof item.blob.id === "string") used.add(item.blob.id)
- return item
- }),
- )
- db.select({ id: blobs.id })
- .from(blobs)
- .all()
- .filter(({ id }) => !used.has(id))
- .forEach(({ id }) => db.delete(blobs).where(eq(blobs.id, id)).run())
- const pending = new Map()
- let timer: ReturnType | undefined
- const flush = () => {
- if (timer) clearTimeout(timer)
- timer = undefined
- const writes = [...pending]
- pending.clear()
- db.transaction((tx) => {
- writes.forEach(([key, value]) => {
- if (value === null) tx.delete(documents).where(eq(documents.key, key)).run()
- else
- tx.insert(documents)
- .values({ key, value })
- .onConflictDoUpdate({ target: documents.key, set: { value } })
- .run()
- })
- })
- }
- const schedule = () => {
- if (!timer) timer = setTimeout(flush, 500)
- }
- return {
- get: (key: string) =>
- pending.has(key)
- ? (pending.get(key) ?? null)
- : (db.select({ value: documents.value }).from(documents).where(eq(documents.key, key)).get()?.value ?? null),
- set(key: string, value: string | null) {
- pending.set(key, value)
- schedule()
- },
- putBlob(data: Uint8Array) {
- const id = createHash("sha256").update(data).digest("hex")
- db.insert(blobs)
- .values({ id, data: Buffer.from(data) })
- .onConflictDoNothing()
- .run()
- return id
- },
- getBlob: (id: string) => db.select({ data: blobs.data }).from(blobs).where(eq(blobs.id, id)).get()?.data ?? null,
- flush,
- close() {
- flush()
- native.close()
- },
- }
-}
diff --git a/packages/desktop/src/main/index.ts b/packages/desktop/src/main/index.ts
index e920b60257..556fd26d96 100644
--- a/packages/desktop/src/main/index.ts
+++ b/packages/desktop/src/main/index.ts
@@ -171,7 +171,7 @@ const main = Effect.gen(function* () {
setAppQuitting()
void stopSidecars().finally(() => {
app.relaunch()
- app.quit()
+ app.exit(0)
})
}
@@ -245,7 +245,7 @@ const main = Effect.gen(function* () {
for (const signal of ["SIGINT", "SIGTERM"] as const) {
process.on(signal, () => {
setAppQuitting()
- void stopSidecars().finally(() => app.quit())
+ void stopSidecars().finally(() => app.exit(0))
})
}
diff --git a/packages/desktop/src/main/ipc.ts b/packages/desktop/src/main/ipc.ts
index bd7a3a7554..f3208a70f3 100644
--- a/packages/desktop/src/main/ipc.ts
+++ b/packages/desktop/src/main/ipc.ts
@@ -1,6 +1,6 @@
import { execFile } from "node:child_process"
import { stat } from "node:fs/promises"
-import { basename, join } from "node:path"
+import { basename } from "node:path"
import { app, BrowserWindow, clipboard, dialog, ipcMain, shell } from "electron"
import type { IpcMainEvent, IpcMainInvokeEvent } from "electron"
import type { DesktopMenuAction } from "@opencode-ai/app/desktop-menu"
@@ -21,7 +21,6 @@ import {
} from "./windows"
import type { UpdaterController } from "./updater-controller"
import { createUpdaterSubscriptions } from "./updater-subscriptions"
-import { createDesktopDraftStore } from "./draft-store"
const pickerFilters = (ext?: string[]) => {
if (!ext || ext.length === 0) return undefined
@@ -52,12 +51,8 @@ type Deps = {
}
export function registerIpcHandlers(deps: Deps) {
- const drafts = createDesktopDraftStore(join(app.getPath("userData"), "drafts.sqlite"))
const updaterSubscriptions = createUpdaterSubscriptions()
app.once("will-quit", updaterSubscriptions.clear)
- app.on("before-quit", () => drafts.flush())
- app.once("will-quit", () => drafts.close())
- app.on("browser-window-created", (_event, win) => win.on("session-end", () => drafts.flush()))
ipcMain.handle("kill-sidecar", () => deps.killSidecar())
ipcMain.handle("await-initialization", () => deps.awaitInitialization())
@@ -128,14 +123,6 @@ export function registerIpcHandlers(deps: Deps) {
const store = getStore(name)
return Object.keys(store.store).length
})
- ipcMain.handle("draft-get", (_event, key: string) => drafts.get(key))
- ipcMain.handle("draft-set", (_event, key: string, value: string) => drafts.set(key, value))
- ipcMain.handle("draft-delete", (_event, key: string) => drafts.set(key, null))
- ipcMain.handle("draft-blob-put", (_event, data: ArrayBuffer) => drafts.putBlob(new Uint8Array(data)))
- ipcMain.handle("draft-blob-get", (_event, id: string) => {
- const data = drafts.getBlob(id)
- return data ? data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength) : null
- })
ipcMain.handle(
"open-directory-picker",
diff --git a/packages/desktop/src/preload/index.ts b/packages/desktop/src/preload/index.ts
index 6b8bd4dfa7..270ff4e576 100644
--- a/packages/desktop/src/preload/index.ts
+++ b/packages/desktop/src/preload/index.ts
@@ -73,11 +73,6 @@ const api: ElectronAPI = {
storeClear: (name) => ipcRenderer.invoke("store-clear", name),
storeKeys: (name) => ipcRenderer.invoke("store-keys", name),
storeLength: (name) => ipcRenderer.invoke("store-length", name),
- draftGet: (key) => ipcRenderer.invoke("draft-get", key),
- draftSet: (key, value) => ipcRenderer.invoke("draft-set", key, value),
- draftDelete: (key) => ipcRenderer.invoke("draft-delete", key),
- draftBlobPut: (data) => ipcRenderer.invoke("draft-blob-put", data),
- draftBlobGet: (id) => ipcRenderer.invoke("draft-blob-get", id),
getWindowID: () => ipcRenderer.invoke("get-window-id"),
onMenuCommand: (cb) => {
diff --git a/packages/desktop/src/preload/types.ts b/packages/desktop/src/preload/types.ts
index fbf58f1fd6..3542a11191 100644
--- a/packages/desktop/src/preload/types.ts
+++ b/packages/desktop/src/preload/types.ts
@@ -63,11 +63,6 @@ export type ElectronAPI = {
storeClear: (name: string) => Promise
storeKeys: (name: string) => Promise
storeLength: (name: string) => Promise
- draftGet: (key: string) => Promise
- draftSet: (key: string, value: string) => Promise
- draftDelete: (key: string) => Promise
- draftBlobPut: (data: ArrayBuffer) => Promise
- draftBlobGet: (id: string) => Promise
getWindowID: () => Promise
onMenuCommand: (cb: (id: string) => void) => () => void
diff --git a/packages/desktop/src/renderer/index.tsx b/packages/desktop/src/renderer/index.tsx
index e1ff8fbfc2..244b5eb405 100644
--- a/packages/desktop/src/renderer/index.tsx
+++ b/packages/desktop/src/renderer/index.tsx
@@ -9,7 +9,6 @@ import {
type Locale,
type Platform,
PlatformProvider,
- createDraftStore,
ServerConnection,
useCommand,
useWslServers,
@@ -227,13 +226,6 @@ const createPlatform = (windowState: DesktopWindowState): Platform => {
},
storage,
- draftStore: createDraftStore({
- get: window.api.draftGet,
- set: window.api.draftSet,
- remove: window.api.draftDelete,
- putBlob: (blob) => blob.arrayBuffer().then(window.api.draftBlobPut),
- getBlob: (id) => window.api.draftBlobGet(id).then((data) => data && new Blob([data])),
- }),
updater: {
state: updaterState,
diff --git a/packages/effect-drizzle-sqlite/package.json b/packages/effect-drizzle-sqlite/package.json
index c5a637c4e3..9577e7a463 100644
--- a/packages/effect-drizzle-sqlite/package.json
+++ b/packages/effect-drizzle-sqlite/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.18.11",
+ "version": "1.18.10",
"name": "@opencode-ai/effect-drizzle-sqlite",
"type": "module",
"license": "MIT",
diff --git a/packages/effect-sqlite-node/package.json b/packages/effect-sqlite-node/package.json
index 8274aee610..7c084da87b 100644
--- a/packages/effect-sqlite-node/package.json
+++ b/packages/effect-sqlite-node/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.18.11",
+ "version": "1.18.10",
"name": "@opencode-ai/effect-sqlite-node",
"type": "module",
"license": "MIT",
diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json
index 1ca75a6381..117d2220ad 100644
--- a/packages/enterprise/package.json
+++ b/packages/enterprise/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/enterprise",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/function/package.json b/packages/function/package.json
index 096c350399..f8e1ee3d86 100644
--- a/packages/function/package.json
+++ b/packages/function/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/function",
- "version": "1.18.11",
+ "version": "1.18.10",
"$schema": "https://json.schemastore.org/package.json",
"private": true,
"type": "module",
diff --git a/packages/http-recorder/package.json b/packages/http-recorder/package.json
index 99147a95a3..56224a41c7 100644
--- a/packages/http-recorder/package.json
+++ b/packages/http-recorder/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.18.11",
+ "version": "1.18.10",
"name": "@opencode-ai/http-recorder",
"description": "Record and replay Effect HTTP client traffic with deterministic cassettes",
"type": "module",
diff --git a/packages/llm/package.json b/packages/llm/package.json
index 908852b3cc..d575867f1c 100644
--- a/packages/llm/package.json
+++ b/packages/llm/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.18.11",
+ "version": "1.18.10",
"name": "@opencode-ai/llm",
"type": "module",
"license": "MIT",
diff --git a/packages/opencode/package.json b/packages/opencode/package.json
index 946102e5e2..84f03d88ab 100644
--- a/packages/opencode/package.json
+++ b/packages/opencode/package.json
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
- "version": "1.18.11",
+ "version": "1.18.10",
"name": "opencode",
"type": "module",
"license": "MIT",
diff --git a/packages/plugin/package.json b/packages/plugin/package.json
index b95531d62e..33b6d2b0dc 100644
--- a/packages/plugin/package.json
+++ b/packages/plugin/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/plugin",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"scripts": {
diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json
index aa86ed50b5..68313859b6 100644
--- a/packages/sdk/js/package.json
+++ b/packages/sdk/js/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/sdk",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"scripts": {
diff --git a/packages/server/package.json b/packages/server/package.json
index b0094607fc..fcfa76143e 100644
--- a/packages/server/package.json
+++ b/packages/server/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/server",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/session-ui/package.json b/packages/session-ui/package.json
index dddef7f277..834b899b4c 100644
--- a/packages/session-ui/package.json
+++ b/packages/session-ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/session-ui",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/session-ui/src/v2/components/prompt-input/attachments.ts b/packages/session-ui/src/v2/components/prompt-input/attachments.ts
index 89f38ec4a3..afa97a7f3e 100644
--- a/packages/session-ui/src/v2/components/prompt-input/attachments.ts
+++ b/packages/session-ui/src/v2/components/prompt-input/attachments.ts
@@ -78,7 +78,6 @@ export type PromptInputV2AttachmentConfig = {
onError: (error: unknown) => void
readClipboardImage?: () => Promise
getPathForFile?: (file: File) => string
- store?: (file: File) => Promise<{ id: string; url: string }>
}
export function createPromptInputV2Attachments(
@@ -103,7 +102,8 @@ export function createPromptInputV2Attachments(
if (toast) input.warn()
return false
}
- const blob = input.store ? await input.store(file) : await blobReference(file)
+ const url = await dataUrl(file, mime)
+ if (!url) return false
const sourcePath = input.getPathForFile?.(file) || undefined
// Native clipboard images arrive with a fresh timestamped filename on every paste, so identical
// clipboard content is matched on bytes alone.
@@ -112,7 +112,7 @@ export function createPromptInputV2Attachments(
.some(
(part) =>
part.type === "image" &&
- part.blob.id === blob.id &&
+ part.dataUrl === url &&
(sourcePath
? part.sourcePath === sourcePath
: !part.sourcePath && (clipboard || part.filename === file.name)),
@@ -127,7 +127,7 @@ export function createPromptInputV2Attachments(
filename: file.name,
sourcePath,
mime,
- blob,
+ dataUrl: url,
}
target.prompt.set([...target.prompt.current(), attachment], target.cursor)
return true
@@ -219,14 +219,20 @@ export function createPromptInputV2Attachments(
}
}
-const imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"])
-
-async function blobReference(file: File) {
- const id = Array.from(new Uint8Array(await crypto.subtle.digest("SHA-256", await file.arrayBuffer())))
- .map((byte) => byte.toString(16).padStart(2, "0"))
- .join("")
- return { id, url: URL.createObjectURL(file) }
+function dataUrl(file: File, mime: string) {
+ return new Promise((resolve) => {
+ const reader = new FileReader()
+ reader.addEventListener("error", () => resolve(""))
+ reader.addEventListener("load", () => {
+ const value = typeof reader.result === "string" ? reader.result : ""
+ const index = value.indexOf(",")
+ resolve(index === -1 ? value : `data:${mime};base64,${value.slice(index + 1)}`)
+ })
+ reader.readAsDataURL(file)
+ })
}
+
+const imageMimes = new Set(["image/png", "image/jpeg", "image/gif", "image/webp"])
const imageExtensions = new Map([
["gif", "image/gif"],
["jpeg", "image/jpeg"],
diff --git a/packages/session-ui/src/v2/components/prompt-input/index.tsx b/packages/session-ui/src/v2/components/prompt-input/index.tsx
index d29fd4df23..0989e2ef65 100644
--- a/packages/session-ui/src/v2/components/prompt-input/index.tsx
+++ b/packages/session-ui/src/v2/components/prompt-input/index.tsx
@@ -212,20 +212,20 @@ export function PromptInputV2(props: PromptInputV2Props) {
onContext={props.controller.openContext}
onShell={props.controller.openShell}
/>
-
+
{(control) => (
-
+
)}
+
{(control) => (
)}
@@ -234,13 +234,13 @@ export function PromptInputV2(props: PromptInputV2Props) {
>
{props.modelControl}
-
+
{(control) => (
- 1}>
+ 1}>
)}
@@ -425,7 +425,7 @@ export function PromptInputV2Attachments(props: {
}
>
props.onAttachmentClick?.(attachment)}
diff --git a/packages/session-ui/src/v2/components/prompt-input/prompt-input.stories.tsx b/packages/session-ui/src/v2/components/prompt-input/prompt-input.stories.tsx
index 6c535b0284..525c264097 100644
--- a/packages/session-ui/src/v2/components/prompt-input/prompt-input.stories.tsx
+++ b/packages/session-ui/src/v2/components/prompt-input/prompt-input.stories.tsx
@@ -121,7 +121,7 @@ function ControlledPromptInput() {
id: "attachment-1",
filename: "requirements.md",
mime: "text/markdown",
- blob: { id: "requirements", url: "data:text/markdown;base64,IyBSZXF1aXJlbWVudHM=" },
+ dataUrl: "data:text/markdown;base64,IyBSZXF1aXJlbWVudHM=",
},
],
cursor: 0,
@@ -199,7 +199,7 @@ function ControlledPromptInput() {
id: `attachment-${store.state.prompt.filter((part) => part.type === "image").length + 1}`,
filename,
mime,
- blob: { id: filename, url: `data:${mime};base64,` },
+ dataUrl: `data:${mime};base64,`,
})
}
diff --git a/packages/session-ui/src/v2/components/prompt-input/store.test.ts b/packages/session-ui/src/v2/components/prompt-input/store.test.ts
index 768a222450..a58428d9c1 100644
--- a/packages/session-ui/src/v2/components/prompt-input/store.test.ts
+++ b/packages/session-ui/src/v2/components/prompt-input/store.test.ts
@@ -13,7 +13,7 @@ function createPromptStore() {
id: "attachment-1",
filename: "notes.txt",
mime: "text/plain",
- blob: { id: "a", url: "blob:a" },
+ dataUrl: "data:text/plain;base64,",
},
],
cursor: 3,
@@ -50,7 +50,7 @@ describe("prompt input v2 store", () => {
id: "attachment-1",
filename: "notes.txt",
mime: "text/plain",
- blob: { id: "a", url: "blob:a" },
+ dataUrl: "data:text/plain;base64,",
},
])
expect(prompt.state.cursor).toBe(7)
diff --git a/packages/session-ui/src/v2/components/prompt-input/types.ts b/packages/session-ui/src/v2/components/prompt-input/types.ts
index c6b47a92ce..a2630a5ea6 100644
--- a/packages/session-ui/src/v2/components/prompt-input/types.ts
+++ b/packages/session-ui/src/v2/components/prompt-input/types.ts
@@ -31,7 +31,7 @@ export type PromptInputV2Attachment = {
filename: string
sourcePath?: string
mime: string
- blob: { id: string; url: string }
+ dataUrl: string
}
export type PromptInputV2Prompt = (
diff --git a/packages/slack/package.json b/packages/slack/package.json
index 46d7d185e3..20f1ce0598 100644
--- a/packages/slack/package.json
+++ b/packages/slack/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/slack",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"scripts": {
diff --git a/packages/stats/app/package.json b/packages/stats/app/package.json
index a04d6761a7..3a19ff5aad 100644
--- a/packages/stats/app/package.json
+++ b/packages/stats/app/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/stats-app",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/stats/core/package.json b/packages/stats/core/package.json
index e02d8e1314..c139702674 100644
--- a/packages/stats/core/package.json
+++ b/packages/stats/core/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/stats-core",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/stats/server/package.json b/packages/stats/server/package.json
index 9eb222ec80..efa68e21dc 100644
--- a/packages/stats/server/package.json
+++ b/packages/stats/server/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/stats-server",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/tui/package.json b/packages/tui/package.json
index e1bc700ac7..a96b6a7088 100644
--- a/packages/tui/package.json
+++ b/packages/tui/package.json
@@ -1,7 +1,7 @@
{
"$schema": "https://json.schemastore.org/package.json",
"name": "@opencode-ai/tui",
- "version": "1.18.11",
+ "version": "1.18.10",
"private": true,
"type": "module",
"license": "MIT",
diff --git a/packages/ui/package.json b/packages/ui/package.json
index 957f3151e9..36cd5ad027 100644
--- a/packages/ui/package.json
+++ b/packages/ui/package.json
@@ -1,6 +1,6 @@
{
"name": "@opencode-ai/ui",
- "version": "1.18.11",
+ "version": "1.18.10",
"type": "module",
"license": "MIT",
"repository": {
diff --git a/packages/web/package.json b/packages/web/package.json
index c9637aee6b..260ca51941 100644
--- a/packages/web/package.json
+++ b/packages/web/package.json
@@ -2,7 +2,7 @@
"name": "@opencode-ai/web",
"type": "module",
"license": "MIT",
- "version": "1.18.11",
+ "version": "1.18.10",
"scripts": {
"dev": "astro dev",
"dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev",
diff --git a/packages/web/src/content/docs/ar/go.mdx b/packages/web/src/content/docs/ar/go.mdx
index b0be0b6157..f885517639 100644
--- a/packages/web/src/content/docs/ar/go.mdx
+++ b/packages/web/src/content/docs/ar/go.mdx
@@ -60,7 +60,6 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال
- DeepSeek V4 Flash — 790 input، و68,000 cached، و280 output tokens لكل طلب
- MiniMax M3 — 510 input، و56,000 cached، و190 output tokens لكل طلب
- MiniMax M2.7 — 300 input، و55,000 cached، و125 output tokens لكل طلب
-- Qwen3.8 Max — 420 input، و66,000 cached، و200 output tokens لكل طلب
- Qwen3.7 Max — 420 input، و66,000 cached، و200 output tokens لكل طلب
- Qwen3.7 Plus — 500 input، و57,000 cached، و190 output tokens لكل طلب
- Qwen3.6 Plus — 500 input، و57,000 cached، و190 output tokens لكل طلب
@@ -141,7 +138,6 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | غير مستخدَمة | 0 أيام |
| MiMo-V2.5-Pro | غير مستخدَمة | 0 أيام |
| MiMo-V2.5 | غير مستخدَمة | 0 أيام |
-| Qwen3.8 Max | غير مستخدَمة | 0 أيام |
| Qwen3.7 Max | غير مستخدَمة | 0 أيام |
| Qwen3.7 Plus | غير مستخدَمة | 0 أيام |
| Qwen3.6 Plus | غير مستخدَمة | 0 أيام |
| MiniMax M3 | غير مستخدَمة | 0 أيام |
| MiniMax M2.7 | غير مستخدَمة | 0 أيام |
| DeepSeek V4 Pro | غير مستخدَمة | 0 أيام |
-| DeepSeek V4 Flash | غير مستخدَمة | 0 أيام |
+| DeepSeek V4 Flash | مستخدَمة | لا توجد اتفاقية |
| Hy3 | غير مستخدَمة | 0 أيام |
- **Grok 4.5:** تعطّل ZDR ميزات API مهمة تعتمد على البيانات المخزنة، بما في ذلك Responses API ذات الحالة، وFiles and Collections، وBatch API. [اعرف المزيد](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** تُنشأ سجلات مراقبة إساءة الاستخدام لكل استخدام لميزات API، ويُحتفظ بها لمدة تصل إلى 30 يومًا. [اعرف المزيد](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** تُجدَّد اتفاقية ZDR شهريًا. الاتفاقية الحالية سارية حتى 31 أغسطس 2026.
---
diff --git a/packages/web/src/content/docs/ar/zen.mdx b/packages/web/src/content/docs/ar/zen.mdx
index 0cc94de6ef..83aeb104c5 100644
--- a/packages/web/src/content/docs/ar/zen.mdx
+++ b/packages/web/src/content/docs/ar/zen.mdx
@@ -90,8 +90,8 @@ OpenCode Zen هي بوابة AI تتيح لك الوصول إلى هذه الن
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/bs/go.mdx b/packages/web/src/content/docs/bs/go.mdx
index 634b3a8685..a5166f7528 100644
--- a/packages/web/src/content/docs/bs/go.mdx
+++ b/packages/web/src/content/docs/bs/go.mdx
@@ -70,7 +70,6 @@ Trenutna lista modela uključuje:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ Tabela ispod pruža procijenjeni broj zahtjeva na osnovu tipičnih obrazaca kori
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -126,7 +124,6 @@ Procjene se zasnivaju na zapaženim obrascima zahtjeva:
- DeepSeek V4 Flash — 790 ulaznih, 68,000 keširanih, 280 izlaznih tokena po zahtjevu
- MiniMax M3 — 510 ulaznih, 56,000 keširanih, 190 izlaznih tokena po zahtjevu
- MiniMax M2.7 — 300 ulaznih, 55,000 keširanih, 125 izlaznih tokena po zahtjevu
-- Qwen3.8 Max — 420 ulaznih, 66,000 keširanih, 200 izlaznih tokena po zahtjevu
- Qwen3.7 Max — 420 ulaznih, 66,000 keširanih, 200 izlaznih tokena po zahtjevu
- Qwen3.7 Plus — 500 ulaznih, 57,000 keširanih, 190 izlaznih tokena po zahtjevu
- Qwen3.6 Plus — 500 ulaznih, 57,000 keširanih, 190 izlaznih tokena po zahtjevu
@@ -151,7 +148,6 @@ Procjene se također zasnivaju na sljedećim cijenama po 1M tokena i mjesečnoj
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ Također možete pristupiti Go modelima putem sljedećih API endpointa.
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Ne koristi se | 0 dana |
| MiMo-V2.5-Pro | Ne koristi se | 0 dana |
| MiMo-V2.5 | Ne koristi se | 0 dana |
-| Qwen3.8 Max | Ne koristi se | 0 dana |
| Qwen3.7 Max | Ne koristi se | 0 dana |
| Qwen3.7 Plus | Ne koristi se | 0 dana |
| Qwen3.6 Plus | Ne koristi se | 0 dana |
| MiniMax M3 | Ne koristi se | 0 dana |
| MiniMax M2.7 | Ne koristi se | 0 dana |
| DeepSeek V4 Pro | Ne koristi se | 0 dana |
-| DeepSeek V4 Flash | Ne koristi se | 0 dana |
+| DeepSeek V4 Flash | Koristi se | Nema sporazuma |
| Hy3 | Ne koristi se | 0 dana |
- **Grok 4.5:** ZDR onemogućava važne API funkcije koje zavise od pohranjenih podataka, uključujući Responses API s očuvanjem stanja, Files and Collections i Batch API. [Saznajte više](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Zapisi o nadzoru zloupotrebe generišu se za svako korištenje API funkcija i čuvaju do 30 dana. [Saznajte više](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** ZDR sporazum obnavlja se mjesečno. Trenutni sporazum važi do 31. augusta 2026.
---
diff --git a/packages/web/src/content/docs/bs/zen.mdx b/packages/web/src/content/docs/bs/zen.mdx
index 17cf73581b..82f85e9198 100644
--- a/packages/web/src/content/docs/bs/zen.mdx
+++ b/packages/web/src/content/docs/bs/zen.mdx
@@ -95,8 +95,8 @@ Našim modelima možete pristupiti i preko sljedećih API endpointa.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/da/go.mdx b/packages/web/src/content/docs/da/go.mdx
index 5aabcc7c43..3ea1bacc19 100644
--- a/packages/web/src/content/docs/da/go.mdx
+++ b/packages/web/src/content/docs/da/go.mdx
@@ -70,7 +70,6 @@ Den nuværende liste over modeller inkluderer:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ Tabellen nedenfor giver et estimeret antal anmodninger baseret på typiske Go-fo
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -126,7 +124,6 @@ Estimaterne er baseret på observerede anmodningsmønstre:
- DeepSeek V4 Flash — 790 input, 68.000 cachelagrede, 280 output-tokens pr. anmodning
- MiniMax M3 — 510 input, 56.000 cachelagrede, 190 output-tokens pr. anmodning
- MiniMax M2.7 — 300 input, 55.000 cachelagrede, 125 output-tokens pr. anmodning
-- Qwen3.8 Max — 420 input, 66.000 cachelagrede, 200 output-tokens pr. anmodning
- Qwen3.7 Max — 420 input, 66.000 cachelagrede, 200 output-tokens pr. anmodning
- Qwen3.7 Plus — 500 input, 57.000 cachelagrede, 190 output-tokens pr. anmodning
- Qwen3.6 Plus — 500 input, 57.000 cachelagrede, 190 output-tokens pr. anmodning
@@ -151,7 +148,6 @@ Estimaterne er også baseret på følgende priser pr. 1M tokens og det månedlig
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ Du kan også få adgang til Go-modeller gennem følgende API-endpoints.
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Ikke brugt | 0 dage |
| MiMo-V2.5-Pro | Ikke brugt | 0 dage |
| MiMo-V2.5 | Ikke brugt | 0 dage |
-| Qwen3.8 Max | Ikke brugt | 0 dage |
| Qwen3.7 Max | Ikke brugt | 0 dage |
| Qwen3.7 Plus | Ikke brugt | 0 dage |
| Qwen3.6 Plus | Ikke brugt | 0 dage |
| MiniMax M3 | Ikke brugt | 0 dage |
| MiniMax M2.7 | Ikke brugt | 0 dage |
| DeepSeek V4 Pro | Ikke brugt | 0 dage |
-| DeepSeek V4 Flash | Ikke brugt | 0 dage |
+| DeepSeek V4 Flash | Brugt | Ingen aftale |
| Hy3 | Ikke brugt | 0 dage |
- **Grok 4.5:** ZDR deaktiverer vigtige API-funktioner, der afhænger af lagrede data, herunder den tilstandsbevarende Responses API, Files and Collections og Batch API. [Læs mere](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Logfiler til overvågning af misbrug genereres ved al brug af API-funktioner og opbevares i op til 30 dage. [Læs mere](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** ZDR-aftalen fornyes månedligt. Den nuværende aftale er gyldig til og med 31. august 2026.
---
diff --git a/packages/web/src/content/docs/da/zen.mdx b/packages/web/src/content/docs/da/zen.mdx
index e200e14e60..c7545e170b 100644
--- a/packages/web/src/content/docs/da/zen.mdx
+++ b/packages/web/src/content/docs/da/zen.mdx
@@ -95,8 +95,8 @@ Du kan også få adgang til vores modeller gennem følgende API-endpoints.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/de/go.mdx b/packages/web/src/content/docs/de/go.mdx
index 73a11d454f..061b3840eb 100644
--- a/packages/web/src/content/docs/de/go.mdx
+++ b/packages/web/src/content/docs/de/go.mdx
@@ -62,7 +62,6 @@ Die aktuelle Liste der Modelle umfasst:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -99,8 +98,7 @@ Die folgende Tabelle zeigt eine geschätzte Anzahl von Anfragen basierend auf ty
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -118,7 +116,6 @@ Die Schätzungen basieren auf beobachteten Anfragemustern:
- DeepSeek V4 Flash — 790 Input-, 68.000 Cached-, 280 Output-Tokens pro Anfrage
- MiniMax M3 — 510 Input-, 56.000 Cached-, 190 Output-Tokens pro Anfrage
- MiniMax M2.7 — 300 Input-, 55.000 Cached-, 125 Output-Tokens pro Anfrage
-- Qwen3.8 Max — 420 Input-, 66.000 Cached-, 200 Output-Tokens pro Anfrage
- Qwen3.7 Max — 420 Input-, 66.000 Cached-, 200 Output-Tokens pro Anfrage
- Qwen3.7 Plus — 500 Input-, 57.000 Cached-, 190 Output-Tokens pro Anfrage
- Qwen3.6 Plus — 500 Input-, 57.000 Cached-, 190 Output-Tokens pro Anfrage
@@ -143,7 +140,6 @@ Die Schätzungen basieren außerdem auf den folgenden Preisen pro 1M Tokens und
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -201,7 +197,6 @@ Du kannst auf die Go-Modelle auch über die folgenden API-Endpunkte zugreifen.
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -223,30 +218,28 @@ https://opencode.ai/zen/go/v1/models
## Datenschutz
-| Modell | Modelltraining | Datenaufbewahrung |
-| ----------------- | --------------- | ----------------- |
-| Grok 4.5 | Nicht verwendet | 30 Tage |
-| GPT 5.6 Luna | Nicht verwendet | 30 Tage |
-| GLM-5.2 | Nicht verwendet | 0 Tage |
-| GLM-5.1 | Nicht verwendet | 0 Tage |
-| Kimi K3 | Nicht verwendet | 0 Tage |
-| Kimi K2.7 Code | Nicht verwendet | 0 Tage |
-| Kimi K2.6 | Nicht verwendet | 0 Tage |
-| MiMo-V2.5-Pro | Nicht verwendet | 0 Tage |
-| MiMo-V2.5 | Nicht verwendet | 0 Tage |
-| Qwen3.8 Max | Nicht verwendet | 0 Tage |
-| Qwen3.7 Max | Nicht verwendet | 0 Tage |
-| Qwen3.7 Plus | Nicht verwendet | 0 Tage |
-| Qwen3.6 Plus | Nicht verwendet | 0 Tage |
-| MiniMax M3 | Nicht verwendet | 0 Tage |
-| MiniMax M2.7 | Nicht verwendet | 0 Tage |
-| DeepSeek V4 Pro | Nicht verwendet | 0 Tage |
-| DeepSeek V4 Flash | Nicht verwendet | 0 Tage |
-| Hy3 | Nicht verwendet | 0 Tage |
+| Modell | Modelltraining | Datenaufbewahrung |
+| ----------------- | --------------- | ------------------ |
+| Grok 4.5 | Nicht verwendet | 30 Tage |
+| GPT 5.6 Luna | Nicht verwendet | 30 Tage |
+| GLM-5.2 | Nicht verwendet | 0 Tage |
+| GLM-5.1 | Nicht verwendet | 0 Tage |
+| Kimi K3 | Nicht verwendet | 0 Tage |
+| Kimi K2.7 Code | Nicht verwendet | 0 Tage |
+| Kimi K2.6 | Nicht verwendet | 0 Tage |
+| MiMo-V2.5-Pro | Nicht verwendet | 0 Tage |
+| MiMo-V2.5 | Nicht verwendet | 0 Tage |
+| Qwen3.7 Max | Nicht verwendet | 0 Tage |
+| Qwen3.7 Plus | Nicht verwendet | 0 Tage |
+| Qwen3.6 Plus | Nicht verwendet | 0 Tage |
+| MiniMax M3 | Nicht verwendet | 0 Tage |
+| MiniMax M2.7 | Nicht verwendet | 0 Tage |
+| DeepSeek V4 Pro | Nicht verwendet | 0 Tage |
+| DeepSeek V4 Flash | Verwendet | Keine Vereinbarung |
+| Hy3 | Nicht verwendet | 0 Tage |
- **Grok 4.5:** ZDR deaktiviert wichtige API-Funktionen, die von gespeicherten Daten abhängen, einschließlich der zustandsbehafteten Responses API, Files and Collections und der Batch API. [Mehr erfahren](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Für die Nutzung aller API-Funktionen werden Protokolle zur Missbrauchsüberwachung erstellt und bis zu 30 Tage lang aufbewahrt. [Mehr erfahren](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** Die ZDR-Vereinbarung wird monatlich erneuert. Die aktuelle Vereinbarung gilt bis einschließlich 31. August 2026.
---
diff --git a/packages/web/src/content/docs/de/zen.mdx b/packages/web/src/content/docs/de/zen.mdx
index 1fa6cbc7eb..a5ac30e060 100644
--- a/packages/web/src/content/docs/de/zen.mdx
+++ b/packages/web/src/content/docs/de/zen.mdx
@@ -86,8 +86,8 @@ Du kannst auch über die folgenden API-Endpunkte auf unsere Modelle zugreifen.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/es/go.mdx b/packages/web/src/content/docs/es/go.mdx
index 7182d716fc..c0908c7dcb 100644
--- a/packages/web/src/content/docs/es/go.mdx
+++ b/packages/web/src/content/docs/es/go.mdx
@@ -70,7 +70,6 @@ La lista actual de modelos incluye:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ La siguiente tabla proporciona una cantidad estimada de peticiones basada en los
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -126,7 +124,6 @@ Las estimaciones se basan en los patrones de peticiones observados:
- DeepSeek V4 Flash — 790 tokens de entrada, 68,000 en caché, 280 tokens de salida por petición
- MiniMax M3 — 510 tokens de entrada, 56,000 en caché, 190 tokens de salida por petición
- MiniMax M2.7 — 300 tokens de entrada, 55,000 en caché, 125 tokens de salida por petición
-- Qwen3.8 Max — 420 tokens de entrada, 66,000 en caché, 200 tokens de salida por petición
- Qwen3.7 Max — 420 tokens de entrada, 66,000 en caché, 200 tokens de salida por petición
- Qwen3.7 Plus — 500 tokens de entrada, 57,000 en caché, 190 tokens de salida por petición
- Qwen3.6 Plus — 500 tokens de entrada, 57,000 en caché, 190 tokens de salida por petición
@@ -151,7 +148,6 @@ Las estimaciones también se basan en los siguientes precios por 1M tokens y en
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ También puedes acceder a los modelos de Go a través de los siguientes endpoint
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | No utilizado | 0 días |
| MiMo-V2.5-Pro | No utilizado | 0 días |
| MiMo-V2.5 | No utilizado | 0 días |
-| Qwen3.8 Max | No utilizado | 0 días |
| Qwen3.7 Max | No utilizado | 0 días |
| Qwen3.7 Plus | No utilizado | 0 días |
| Qwen3.6 Plus | No utilizado | 0 días |
| MiniMax M3 | No utilizado | 0 días |
| MiniMax M2.7 | No utilizado | 0 días |
| DeepSeek V4 Pro | No utilizado | 0 días |
-| DeepSeek V4 Flash | No utilizado | 0 días |
+| DeepSeek V4 Flash | Utilizado | Sin acuerdo |
| Hy3 | No utilizado | 0 días |
- **Grok 4.5:** ZDR deshabilita funciones importantes de la API que dependen de datos almacenados, incluidas la Responses API con estado, Files and Collections y la Batch API. [Más información](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Se generan registros de supervisión de abusos para todo el uso de funciones de la API y se conservan durante un máximo de 30 días. [Más información](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** El acuerdo de ZDR se renueva mensualmente. El acuerdo actual es válido hasta el 31 de agosto de 2026.
---
diff --git a/packages/web/src/content/docs/es/zen.mdx b/packages/web/src/content/docs/es/zen.mdx
index 539d5999f6..e37a0592c9 100644
--- a/packages/web/src/content/docs/es/zen.mdx
+++ b/packages/web/src/content/docs/es/zen.mdx
@@ -95,8 +95,8 @@ También puedes acceder a nuestros modelos a través de los siguientes endpoints
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/fr/go.mdx b/packages/web/src/content/docs/fr/go.mdx
index c858645e44..2dc0b75d2f 100644
--- a/packages/web/src/content/docs/fr/go.mdx
+++ b/packages/web/src/content/docs/fr/go.mdx
@@ -60,7 +60,6 @@ La liste actuelle des modèles comprend :
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ Le tableau ci-dessous fournit une estimation du nombre de requêtes basée sur d
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ Les estimations sont basées sur les schémas de requêtes observés :
- DeepSeek V4 Flash — 790 tokens en entrée, 68,000 en cache, 280 tokens en sortie par requête
- MiniMax M3 — 510 tokens en entrée, 56,000 en cache, 190 tokens en sortie par requête
- MiniMax M2.7 — 300 tokens en entrée, 55,000 en cache, 125 tokens en sortie par requête
-- Qwen3.8 Max — 420 tokens en entrée, 66,000 en cache, 200 tokens en sortie par requête
- Qwen3.7 Max — 420 tokens en entrée, 66,000 en cache, 200 tokens en sortie par requête
- Qwen3.7 Plus — 500 tokens en entrée, 57,000 en cache, 190 tokens en sortie par requête
- Qwen3.6 Plus — 500 tokens en entrée, 57,000 en cache, 190 tokens en sortie par requête
@@ -141,7 +138,6 @@ Les estimations sont également basées sur les prix suivants par 1M tokens et s
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ Vous pouvez également accéder aux modèles Go via les points de terminaison d'
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Non utilisé | 0 jour |
| MiMo-V2.5-Pro | Non utilisé | 0 jour |
| MiMo-V2.5 | Non utilisé | 0 jour |
-| Qwen3.8 Max | Non utilisé | 0 jour |
| Qwen3.7 Max | Non utilisé | 0 jour |
| Qwen3.7 Plus | Non utilisé | 0 jour |
| Qwen3.6 Plus | Non utilisé | 0 jour |
| MiniMax M3 | Non utilisé | 0 jour |
| MiniMax M2.7 | Non utilisé | 0 jour |
| DeepSeek V4 Pro | Non utilisé | 0 jour |
-| DeepSeek V4 Flash | Non utilisé | 0 jour |
+| DeepSeek V4 Flash | Utilisé | Aucun accord |
| Hy3 | Non utilisé | 0 jour |
- **Grok 4.5:** Le ZDR désactive d’importantes fonctionnalités API qui dépendent des données stockées, notamment Responses API avec état, Files and Collections et Batch API. [En savoir plus](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Des journaux de surveillance des abus sont générés pour toute utilisation des fonctionnalités API et conservés pendant un maximum de 30 jours. [En savoir plus](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** L’accord ZDR est renouvelé chaque mois. L’accord actuel est valable jusqu’au 31 août 2026.
---
diff --git a/packages/web/src/content/docs/fr/zen.mdx b/packages/web/src/content/docs/fr/zen.mdx
index 7a5d5bcf7b..24fa7341d9 100644
--- a/packages/web/src/content/docs/fr/zen.mdx
+++ b/packages/web/src/content/docs/fr/zen.mdx
@@ -86,8 +86,8 @@ Vous pouvez également accéder à nos modèles via les points de terminaison AP
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/go.mdx b/packages/web/src/content/docs/go.mdx
index 507c901a76..29413ac112 100644
--- a/packages/web/src/content/docs/go.mdx
+++ b/packages/web/src/content/docs/go.mdx
@@ -70,7 +70,6 @@ The current list of models includes:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ The table below provides an estimated request count based on typical Go usage pa
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -128,7 +126,6 @@ The estimates are based on observed request patterns:
- MiniMax M2.7 — 300 input, 55,000 cached, 125 output tokens per request
- MiMo-V2.5 — 830 input, 71,500 cached, 295 output tokens per request
- MiMo-V2.5-Pro — 790 input, 86,000 cached, 305 output tokens per request
-- Qwen3.8 Max — 420 input, 66,000 cached, 200 output tokens per request
- Qwen3.7 Max — 420 input, 66,000 cached, 200 output tokens per request
- Qwen3.7 Plus — 500 input, 57,000 cached, 190 output tokens per request
- Qwen3.6 Plus — 500 input, 57,000 cached, 190 output tokens per request
@@ -151,7 +148,6 @@ The estimates are also based on the following prices per 1M tokens and the month
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ You can also access Go models through the following API endpoints.
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Not used | 0 days |
| MiMo-V2.5-Pro | Not used | 0 days |
| MiMo-V2.5 | Not used | 0 days |
-| Qwen3.8 Max | Not used | 0 days |
| Qwen3.7 Max | Not used | 0 days |
| Qwen3.7 Plus | Not used | 0 days |
| Qwen3.6 Plus | Not used | 0 days |
| MiniMax M3 | Not used | 0 days |
| MiniMax M2.7 | Not used | 0 days |
| DeepSeek V4 Pro | Not used | 0 days |
-| DeepSeek V4 Flash | Not used | 0 days |
+| DeepSeek V4 Flash | Used | No agreement |
| Hy3 | Not used | 0 days |
- **Grok 4.5:** ZDR disables important API features that depend on stored data, including the stateful Responses API, Files and Collections, and the Batch API. [Learn more](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Abuse monitoring logs are generated for all API feature usage and retained for up to 30 days. [Learn more](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** ZDR agreement is renewed monthly. The current agreement is valid through August 31, 2026.
---
diff --git a/packages/web/src/content/docs/it/go.mdx b/packages/web/src/content/docs/it/go.mdx
index a724041640..92726425c8 100644
--- a/packages/web/src/content/docs/it/go.mdx
+++ b/packages/web/src/content/docs/it/go.mdx
@@ -68,7 +68,6 @@ L'elenco attuale dei modelli include:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -105,8 +104,7 @@ La tabella seguente fornisce una stima del conteggio delle richieste in base a p
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -124,7 +122,6 @@ Le stime si basano sui pattern di richieste osservati:
- DeepSeek V4 Flash — 790 di input, 68.000 in cache, 280 token di output per richiesta
- MiniMax M3 — 510 di input, 56.000 in cache, 190 token di output per richiesta
- MiniMax M2.7 — 300 di input, 55.000 in cache, 125 token di output per richiesta
-- Qwen3.8 Max — 420 di input, 66.000 in cache, 200 token di output per richiesta
- Qwen3.7 Max — 420 di input, 66.000 in cache, 200 token di output per richiesta
- Qwen3.7 Plus — 500 di input, 57.000 in cache, 190 token di output per richiesta
- Qwen3.6 Plus — 500 di input, 57.000 in cache, 190 token di output per richiesta
@@ -149,7 +146,6 @@ Le stime si basano anche sui seguenti prezzi per 1M token e sull'utilizzo mensil
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -209,7 +205,6 @@ Puoi anche accedere ai modelli Go tramite i seguenti endpoint API.
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -244,19 +239,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Non utilizzato | 0 giorni |
| MiMo-V2.5-Pro | Non utilizzato | 0 giorni |
| MiMo-V2.5 | Non utilizzato | 0 giorni |
-| Qwen3.8 Max | Non utilizzato | 0 giorni |
| Qwen3.7 Max | Non utilizzato | 0 giorni |
| Qwen3.7 Plus | Non utilizzato | 0 giorni |
| Qwen3.6 Plus | Non utilizzato | 0 giorni |
| MiniMax M3 | Non utilizzato | 0 giorni |
| MiniMax M2.7 | Non utilizzato | 0 giorni |
| DeepSeek V4 Pro | Non utilizzato | 0 giorni |
-| DeepSeek V4 Flash | Non utilizzato | 0 giorni |
+| DeepSeek V4 Flash | Utilizzato | Nessun accordo |
| Hy3 | Non utilizzato | 0 giorni |
- **Grok 4.5:** ZDR disabilita importanti funzionalità API che dipendono dai dati archiviati, tra cui la Responses API con stato, Files and Collections e Batch API. [Scopri di più](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** I log di monitoraggio degli abusi vengono generati per l'utilizzo di tutte le funzionalità API e conservati per un massimo di 30 giorni. [Scopri di più](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** L'accordo ZDR viene rinnovato mensilmente. L'accordo attuale è valido fino al 31 agosto 2026.
---
diff --git a/packages/web/src/content/docs/it/zen.mdx b/packages/web/src/content/docs/it/zen.mdx
index 941db5be94..3e3891b79d 100644
--- a/packages/web/src/content/docs/it/zen.mdx
+++ b/packages/web/src/content/docs/it/zen.mdx
@@ -95,8 +95,8 @@ Puoi anche accedere ai nostri modelli tramite i seguenti endpoint API.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/ja/go.mdx b/packages/web/src/content/docs/ja/go.mdx
index 963a36b1cc..8439341656 100644
--- a/packages/web/src/content/docs/ja/go.mdx
+++ b/packages/web/src/content/docs/ja/go.mdx
@@ -60,7 +60,6 @@ OpenCode Goをサブスクライブできるのは、1つのワークスペー
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ OpenCode Goには以下の制限が含まれています:
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ OpenCode Goには以下の制限が含まれています:
- DeepSeek V4 Flash — リクエストあたり 入力 790トークン、キャッシュ 68,000トークン、出力 280トークン
- MiniMax M3 — リクエストあたり 入力 510トークン、キャッシュ 56,000トークン、出力 190トークン
- MiniMax M2.7 — リクエストあたり 入力 300トークン、キャッシュ 55,000トークン、出力 125トークン
-- Qwen3.8 Max — リクエストあたり 入力 420トークン、キャッシュ 66,000トークン、出力 200トークン
- Qwen3.7 Max — リクエストあたり 入力 420トークン、キャッシュ 66,000トークン、出力 200トークン
- Qwen3.7 Plus — リクエストあたり 入力 500トークン、キャッシュ 57,000トークン、出力 190トークン
- Qwen3.6 Plus — リクエストあたり 入力 500トークン、キャッシュ 57,000トークン、出力 190トークン
@@ -141,7 +138,6 @@ OpenCode Goには以下の制限が含まれています:
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ Goでは月額$10を支払い、その6倍の利用枠を提供することを
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | 使用なし | 0日 |
| MiMo-V2.5-Pro | 使用なし | 0日 |
| MiMo-V2.5 | 使用なし | 0日 |
-| Qwen3.8 Max | 使用なし | 0日 |
| Qwen3.7 Max | 使用なし | 0日 |
| Qwen3.7 Plus | 使用なし | 0日 |
| Qwen3.6 Plus | 使用なし | 0日 |
| MiniMax M3 | 使用なし | 0日 |
| MiniMax M2.7 | 使用なし | 0日 |
| DeepSeek V4 Pro | 使用なし | 0日 |
-| DeepSeek V4 Flash | 使用なし | 0日 |
+| DeepSeek V4 Flash | 使用あり | 契約なし |
| Hy3 | 使用なし | 0日 |
- **Grok 4.5:** ZDRでは、保存データに依存する重要なAPI機能(ステートフルなResponses API、Files and Collections、Batch APIなど)が無効になります。[詳しく見る](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr)。
- **GPT 5.6 Luna:** 不正使用監視ログはすべてのAPI機能の使用時に生成され、最大30日間保持されます。[詳しく見る](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring)。
-- **DeepSeek V4 Flash:** ZDR契約は毎月更新されます。現在の契約は2026年8月31日まで有効です。
---
diff --git a/packages/web/src/content/docs/ja/zen.mdx b/packages/web/src/content/docs/ja/zen.mdx
index 73b8d5a187..f61f826f63 100644
--- a/packages/web/src/content/docs/ja/zen.mdx
+++ b/packages/web/src/content/docs/ja/zen.mdx
@@ -86,8 +86,8 @@ OpenCode Zen は、OpenCode のほかのプロバイダーと同じように動
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/ko/go.mdx b/packages/web/src/content/docs/ko/go.mdx
index 29693cdb6a..30e06f9cc4 100644
--- a/packages/web/src/content/docs/ko/go.mdx
+++ b/packages/web/src/content/docs/ko/go.mdx
@@ -60,7 +60,6 @@ workspace당 한 명의 멤버만 OpenCode Go를 구독할 수 있습니다.
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ OpenCode Go에는 다음과 같은 한도가 포함됩니다.
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ OpenCode Go에는 다음과 같은 한도가 포함됩니다.
- DeepSeek V4 Flash — 요청당 입력 790, 캐시 68,000, 출력 토큰 280
- MiniMax M3 — 요청당 입력 510, 캐시 56,000, 출력 토큰 190
- MiniMax M2.7 — 요청당 입력 300, 캐시 55,000, 출력 토큰 125
-- Qwen3.8 Max — 요청당 입력 420, 캐시 66,000, 출력 토큰 200
- Qwen3.7 Max — 요청당 입력 420, 캐시 66,000, 출력 토큰 200
- Qwen3.7 Plus — 요청당 입력 500, 캐시 57,000, 출력 토큰 190
- Qwen3.6 Plus — 요청당 입력 500, 캐시 57,000, 출력 토큰 190
@@ -141,7 +138,6 @@ OpenCode Go에는 다음과 같은 한도가 포함됩니다.
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ Go에서는 월 $10를 지불하며, 저희는 그 6배의 사용량을 제공
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | 사용되지 않음 | 0일 |
| MiMo-V2.5-Pro | 사용되지 않음 | 0일 |
| MiMo-V2.5 | 사용되지 않음 | 0일 |
-| Qwen3.8 Max | 사용되지 않음 | 0일 |
| Qwen3.7 Max | 사용되지 않음 | 0일 |
| Qwen3.7 Plus | 사용되지 않음 | 0일 |
| Qwen3.6 Plus | 사용되지 않음 | 0일 |
| MiniMax M3 | 사용되지 않음 | 0일 |
| MiniMax M2.7 | 사용되지 않음 | 0일 |
| DeepSeek V4 Pro | 사용되지 않음 | 0일 |
-| DeepSeek V4 Flash | 사용되지 않음 | 0일 |
+| DeepSeek V4 Flash | 사용됨 | 합의 없음 |
| Hy3 | 사용되지 않음 | 0일 |
- **Grok 4.5:** ZDR은 저장된 데이터에 의존하는 중요한 API 기능(상태 저장형 Responses API, Files and Collections, Batch API 포함)을 비활성화합니다. [자세히 알아보기](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** 모든 API 기능 사용에 대해 악용 모니터링 로그가 생성되며 최대 30일 동안 보존됩니다. [자세히 알아보기](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** ZDR 계약은 매월 갱신됩니다. 현재 계약은 2026년 8월 31일까지 유효합니다.
---
diff --git a/packages/web/src/content/docs/ko/zen.mdx b/packages/web/src/content/docs/ko/zen.mdx
index 474bd38ff4..b112aa742d 100644
--- a/packages/web/src/content/docs/ko/zen.mdx
+++ b/packages/web/src/content/docs/ko/zen.mdx
@@ -86,8 +86,8 @@ OpenCode Zen은 OpenCode의 다른 provider와 똑같이 작동합니다.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/nb/go.mdx b/packages/web/src/content/docs/nb/go.mdx
index afcc39e19b..bc13cc0946 100644
--- a/packages/web/src/content/docs/nb/go.mdx
+++ b/packages/web/src/content/docs/nb/go.mdx
@@ -70,7 +70,6 @@ Den nåværende listen over modeller inkluderer:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ Tabellen nedenfor gir et estimert antall forespørsler basert på typiske bruksm
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -126,7 +124,6 @@ Estimatene er basert på observerte forespørselsmønstre:
- DeepSeek V4 Flash — 790 input, 68 000 bufret, 280 output-tokens per forespørsel
- MiniMax M3 — 510 input, 56 000 bufret, 190 output-tokens per forespørsel
- MiniMax M2.7 — 300 input, 55 000 bufret, 125 output-tokens per forespørsel
-- Qwen3.8 Max — 420 input, 66 000 bufret, 200 output-tokens per forespørsel
- Qwen3.7 Max — 420 input, 66 000 bufret, 200 output-tokens per forespørsel
- Qwen3.7 Plus — 500 input, 57 000 bufret, 190 output-tokens per forespørsel
- Qwen3.6 Plus — 500 input, 57 000 bufret, 190 output-tokens per forespørsel
@@ -151,7 +148,6 @@ Estimatene er også basert på følgende priser per 1M tokens og den månedlige
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ Du kan også få tilgang til Go-modeller gjennom følgende API-endepunkter.
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Brukes ikke | 0 dager |
| MiMo-V2.5-Pro | Brukes ikke | 0 dager |
| MiMo-V2.5 | Brukes ikke | 0 dager |
-| Qwen3.8 Max | Brukes ikke | 0 dager |
| Qwen3.7 Max | Brukes ikke | 0 dager |
| Qwen3.7 Plus | Brukes ikke | 0 dager |
| Qwen3.6 Plus | Brukes ikke | 0 dager |
| MiniMax M3 | Brukes ikke | 0 dager |
| MiniMax M2.7 | Brukes ikke | 0 dager |
| DeepSeek V4 Pro | Brukes ikke | 0 dager |
-| DeepSeek V4 Flash | Brukes ikke | 0 dager |
+| DeepSeek V4 Flash | Brukes | Ingen avtale |
| Hy3 | Brukes ikke | 0 dager |
- **Grok 4.5:** ZDR deaktiverer viktige API-funksjoner som er avhengige av lagrede data, inkludert den tilstandsbaserte Responses API, Files and Collections og Batch API. [Les mer](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Logger for overvåking av misbruk genereres for all bruk av API-funksjoner og oppbevares i opptil 30 dager. [Les mer](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** ZDR-avtalen fornyes månedlig. Den gjeldende avtalen er gyldig til og med 31. august 2026.
---
diff --git a/packages/web/src/content/docs/nb/zen.mdx b/packages/web/src/content/docs/nb/zen.mdx
index 74cc45b3a9..379535eb7c 100644
--- a/packages/web/src/content/docs/nb/zen.mdx
+++ b/packages/web/src/content/docs/nb/zen.mdx
@@ -95,8 +95,8 @@ Du kan også få tilgang til modellene våre gjennom følgende API-endepunkter.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/pl/go.mdx b/packages/web/src/content/docs/pl/go.mdx
index f215736964..c15a2c11e5 100644
--- a/packages/web/src/content/docs/pl/go.mdx
+++ b/packages/web/src/content/docs/pl/go.mdx
@@ -64,7 +64,6 @@ Obecna lista modeli obejmuje:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -101,8 +100,7 @@ Poniższa tabela przedstawia szacunkową liczbę żądań na podstawie typowych
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -120,7 +118,6 @@ Szacunki te opierają się na zaobserwowanych wzorcach żądań:
- DeepSeek V4 Flash — 790 tokenów wejściowych, 68 000 w pamięci podręcznej, 280 tokenów wyjściowych na żądanie
- MiniMax M3 — 510 tokenów wejściowych, 56 000 w pamięci podręcznej, 190 tokenów wyjściowych na żądanie
- MiniMax M2.7 — 300 tokenów wejściowych, 55 000 w pamięci podręcznej, 125 tokenów wyjściowych na żądanie
-- Qwen3.8 Max — 420 tokenów wejściowych, 66 000 w pamięci podręcznej, 200 tokenów wyjściowych na żądanie
- Qwen3.7 Max — 420 tokenów wejściowych, 66 000 w pamięci podręcznej, 200 tokenów wyjściowych na żądanie
- Qwen3.7 Plus — 500 tokenów wejściowych, 57 000 w pamięci podręcznej, 190 tokenów wyjściowych na żądanie
- Qwen3.6 Plus — 500 tokenów wejściowych, 57 000 w pamięci podręcznej, 190 tokenów wyjściowych na żądanie
@@ -145,7 +142,6 @@ Szacunki opierają się również na następujących cenach za 1M tokenów oraz
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -203,7 +199,6 @@ Możesz również uzyskać dostęp do modeli Go za pośrednictwem następującyc
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -238,19 +233,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Niewykorzystywane | 0 dni |
| MiMo-V2.5-Pro | Niewykorzystywane | 0 dni |
| MiMo-V2.5 | Niewykorzystywane | 0 dni |
-| Qwen3.8 Max | Niewykorzystywane | 0 dni |
| Qwen3.7 Max | Niewykorzystywane | 0 dni |
| Qwen3.7 Plus | Niewykorzystywane | 0 dni |
| Qwen3.6 Plus | Niewykorzystywane | 0 dni |
| MiniMax M3 | Niewykorzystywane | 0 dni |
| MiniMax M2.7 | Niewykorzystywane | 0 dni |
| DeepSeek V4 Pro | Niewykorzystywane | 0 dni |
-| DeepSeek V4 Flash | Niewykorzystywane | 0 dni |
+| DeepSeek V4 Flash | Wykorzystywane | Brak umowy |
| Hy3 | Niewykorzystywane | 0 dni |
- **Grok 4.5:** ZDR wyłącza ważne funkcje API zależne od przechowywanych danych, w tym stanowy Responses API, Files and Collections oraz Batch API. [Dowiedz się więcej](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Dzienniki monitorowania nadużyć są generowane dla każdego użycia funkcji API i przechowywane przez maksymalnie 30 dni. [Dowiedz się więcej](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** Umowa ZDR jest odnawiana co miesiąc. Obecna umowa obowiązuje do 31 sierpnia 2026 r.
---
diff --git a/packages/web/src/content/docs/pl/zen.mdx b/packages/web/src/content/docs/pl/zen.mdx
index c6c8ba7fb4..a2df69cadf 100644
--- a/packages/web/src/content/docs/pl/zen.mdx
+++ b/packages/web/src/content/docs/pl/zen.mdx
@@ -95,8 +95,8 @@ Możesz też uzyskać dostęp do naszych modeli przez poniższe endpointy API.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/pt-br/go.mdx b/packages/web/src/content/docs/pt-br/go.mdx
index fcfc8ed608..20f4b08b84 100644
--- a/packages/web/src/content/docs/pt-br/go.mdx
+++ b/packages/web/src/content/docs/pt-br/go.mdx
@@ -70,7 +70,6 @@ A lista atual de modelos inclui:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ A tabela abaixo fornece uma contagem estimada de requisições com base nos padr
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -126,7 +124,6 @@ As estimativas se baseiam nos padrões de requisições observados:
- DeepSeek V4 Flash — 790 tokens de entrada, 68.000 em cache, 280 tokens de saída por requisição
- MiniMax M3 — 510 tokens de entrada, 56.000 em cache, 190 tokens de saída por requisição
- MiniMax M2.7 — 300 tokens de entrada, 55.000 em cache, 125 tokens de saída por requisição
-- Qwen3.8 Max — 420 tokens de entrada, 66.000 em cache, 200 tokens de saída por requisição
- Qwen3.7 Max — 420 tokens de entrada, 66.000 em cache, 200 tokens de saída por requisição
- Qwen3.7 Plus — 500 tokens de entrada, 57.000 em cache, 190 tokens de saída por requisição
- Qwen3.6 Plus — 500 tokens de entrada, 57.000 em cache, 190 tokens de saída por requisição
@@ -151,7 +148,6 @@ As estimativas também se baseiam nos seguintes preços por 1M tokens e no uso m
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ Você também pode acessar os modelos do Go através dos seguintes endpoints de
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Não usado | 0 dias |
| MiMo-V2.5-Pro | Não usado | 0 dias |
| MiMo-V2.5 | Não usado | 0 dias |
-| Qwen3.8 Max | Não usado | 0 dias |
| Qwen3.7 Max | Não usado | 0 dias |
| Qwen3.7 Plus | Não usado | 0 dias |
| Qwen3.6 Plus | Não usado | 0 dias |
| MiniMax M3 | Não usado | 0 dias |
| MiniMax M2.7 | Não usado | 0 dias |
| DeepSeek V4 Pro | Não usado | 0 dias |
-| DeepSeek V4 Flash | Não usado | 0 dias |
+| DeepSeek V4 Flash | Usado | Sem acordo |
| Hy3 | Não usado | 0 dias |
- **Grok 4.5:** O ZDR desativa recursos importantes da API que dependem de dados armazenados, incluindo a Responses API com estado, Files and Collections e a Batch API. [Saiba mais](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Logs de monitoramento de abuso são gerados para todo uso de recursos da API e retidos por até 30 dias. [Saiba mais](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** O acordo de ZDR é renovado mensalmente. O acordo atual é válido até 31 de agosto de 2026.
---
diff --git a/packages/web/src/content/docs/pt-br/zen.mdx b/packages/web/src/content/docs/pt-br/zen.mdx
index fa19e0e7d2..a657b88bd1 100644
--- a/packages/web/src/content/docs/pt-br/zen.mdx
+++ b/packages/web/src/content/docs/pt-br/zen.mdx
@@ -86,8 +86,8 @@ Você também pode acessar nossos modelos pelos seguintes endpoints de API.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/ru/go.mdx b/packages/web/src/content/docs/ru/go.mdx
index 4df18953ef..dd3a272f0a 100644
--- a/packages/web/src/content/docs/ru/go.mdx
+++ b/packages/web/src/content/docs/ru/go.mdx
@@ -70,7 +70,6 @@ OpenCode Go работает так же, как и любой другой пр
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -107,8 +106,7 @@ OpenCode Go включает следующие лимиты:
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -126,7 +124,6 @@ OpenCode Go включает следующие лимиты:
- DeepSeek V4 Flash — 790 входных, 68,000 кешированных, 280 выходных токенов на запрос
- MiniMax M3 — 510 входных, 56,000 кешированных, 190 выходных токенов на запрос
- MiniMax M2.7 — 300 входных, 55,000 кешированных, 125 выходных токенов на запрос
-- Qwen3.8 Max — 420 входных, 66,000 кешированных, 200 выходных токенов на запрос
- Qwen3.7 Max — 420 входных, 66,000 кешированных, 200 выходных токенов на запрос
- Qwen3.7 Plus — 500 входных, 57,000 кешированных, 190 выходных токенов на запрос
- Qwen3.6 Plus — 500 входных, 57,000 кешированных, 190 выходных токенов на запрос
@@ -151,7 +148,6 @@ OpenCode Go включает следующие лимиты:
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -211,7 +207,6 @@ OpenCode Go включает следующие лимиты:
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -246,19 +241,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Не используется | 0 дней |
| MiMo-V2.5-Pro | Не используется | 0 дней |
| MiMo-V2.5 | Не используется | 0 дней |
-| Qwen3.8 Max | Не используется | 0 дней |
| Qwen3.7 Max | Не используется | 0 дней |
| Qwen3.7 Plus | Не используется | 0 дней |
| Qwen3.6 Plus | Не используется | 0 дней |
| MiniMax M3 | Не используется | 0 дней |
| MiniMax M2.7 | Не используется | 0 дней |
| DeepSeek V4 Pro | Не используется | 0 дней |
-| DeepSeek V4 Flash | Не используется | 0 дней |
+| DeepSeek V4 Flash | Используется | Нет соглашения |
| Hy3 | Не используется | 0 дней |
- **Grok 4.5:** ZDR отключает важные функции API, зависящие от сохраненных данных, включая Responses API с сохранением состояния, Files and Collections и Batch API. [Подробнее](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Журналы мониторинга злоупотреблений создаются при любом использовании функций API и хранятся до 30 дней. [Подробнее](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** Соглашение ZDR продлевается ежемесячно. Текущее соглашение действует до 31 августа 2026 года.
---
diff --git a/packages/web/src/content/docs/ru/zen.mdx b/packages/web/src/content/docs/ru/zen.mdx
index f9633ac323..4333abf0e5 100644
--- a/packages/web/src/content/docs/ru/zen.mdx
+++ b/packages/web/src/content/docs/ru/zen.mdx
@@ -95,8 +95,8 @@ OpenCode Zen работает как любой другой провайдер
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/th/go.mdx b/packages/web/src/content/docs/th/go.mdx
index f241b77ee0..38c0d9ebaa 100644
--- a/packages/web/src/content/docs/th/go.mdx
+++ b/packages/web/src/content/docs/th/go.mdx
@@ -60,7 +60,6 @@ OpenCode Go ทำงานเหมือนกับผู้ให้บร
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้:
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้:
- DeepSeek V4 Flash — 790 input, 68,000 cached, 280 output tokens ต่อ request
- MiniMax M3 — 510 input, 56,000 cached, 190 output tokens ต่อ request
- MiniMax M2.7 — 300 input, 55,000 cached, 125 output tokens ต่อ request
-- Qwen3.8 Max — 420 input, 66,000 cached, 200 output tokens ต่อ request
- Qwen3.7 Max — 420 input, 66,000 cached, 200 output tokens ต่อ request
- Qwen3.7 Plus — 500 input, 57,000 cached, 190 output tokens ต่อ request
- Qwen3.6 Plus — 500 input, 57,000 cached, 190 output tokens ต่อ request
@@ -141,7 +138,6 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้:
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้:
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | ไม่นำไปใช้ | 0 วัน |
| MiMo-V2.5-Pro | ไม่นำไปใช้ | 0 วัน |
| MiMo-V2.5 | ไม่นำไปใช้ | 0 วัน |
-| Qwen3.8 Max | ไม่นำไปใช้ | 0 วัน |
| Qwen3.7 Max | ไม่นำไปใช้ | 0 วัน |
| Qwen3.7 Plus | ไม่นำไปใช้ | 0 วัน |
| Qwen3.6 Plus | ไม่นำไปใช้ | 0 วัน |
| MiniMax M3 | ไม่นำไปใช้ | 0 วัน |
| MiniMax M2.7 | ไม่นำไปใช้ | 0 วัน |
| DeepSeek V4 Pro | ไม่นำไปใช้ | 0 วัน |
-| DeepSeek V4 Flash | ไม่นำไปใช้ | 0 วัน |
+| DeepSeek V4 Flash | นำไปใช้ | ไม่มีข้อตกลง |
| Hy3 | ไม่นำไปใช้ | 0 วัน |
- **Grok 4.5:** ZDR ปิดใช้งานฟีเจอร์ API สำคัญที่ต้องอาศัยข้อมูลที่จัดเก็บไว้ ซึ่งรวมถึง Responses API แบบมีสถานะ, Files and Collections และ Batch API [ดูข้อมูลเพิ่มเติม](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr)
- **GPT 5.6 Luna:** ระบบจะสร้างบันทึกการตรวจสอบการใช้งานในทางที่ผิดสำหรับการใช้งานฟีเจอร์ API ทั้งหมด และเก็บรักษาไว้นานสูงสุด 30 วัน [ดูข้อมูลเพิ่มเติม](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring)
-- **DeepSeek V4 Flash:** ข้อตกลง ZDR จะต่ออายุทุกเดือน ข้อตกลงปัจจุบันมีผลใช้ถึงวันที่ 31 สิงหาคม 2026
---
diff --git a/packages/web/src/content/docs/th/zen.mdx b/packages/web/src/content/docs/th/zen.mdx
index 2c256704ae..99ba106a3c 100644
--- a/packages/web/src/content/docs/th/zen.mdx
+++ b/packages/web/src/content/docs/th/zen.mdx
@@ -88,8 +88,8 @@ OpenCode Zen ทำงานเหมือน provider อื่น ๆ ใน
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/tr/go.mdx b/packages/web/src/content/docs/tr/go.mdx
index b480e0b2e5..a8861dde24 100644
--- a/packages/web/src/content/docs/tr/go.mdx
+++ b/packages/web/src/content/docs/tr/go.mdx
@@ -60,7 +60,6 @@ Mevcut model listesi şunları içerir:
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ Aşağıdaki tablo, tipik Go kullanım modellerine dayalı tahmini bir istek say
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ Tahminler, gözlemlenen istek modellerine dayanır:
- DeepSeek V4 Flash — İstek başına 790 girdi, 68.000 önbelleğe alınmış, 280 çıktı token'ı
- MiniMax M3 — İstek başına 510 girdi, 56.000 önbelleğe alınmış, 190 çıktı token'ı
- MiniMax M2.7 — İstek başına 300 girdi, 55.000 önbelleğe alınmış, 125 çıktı token'ı
-- Qwen3.8 Max — İstek başına 420 girdi, 66.000 önbelleğe alınmış, 200 çıktı token'ı
- Qwen3.7 Max — İstek başına 420 girdi, 66.000 önbelleğe alınmış, 200 çıktı token'ı
- Qwen3.7 Plus — İstek başına 500 girdi, 57.000 önbelleğe alınmış, 190 çıktı token'ı
- Qwen3.6 Plus — İstek başına 500 girdi, 57.000 önbelleğe alınmış, 190 çıktı token'ı
@@ -141,7 +138,6 @@ Tahminler ayrıca 1M token başına aşağıdaki fiyatlara ve her modelle birlik
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ Go modellerine aşağıdaki API uç noktaları aracılığıyla da erişebilirsi
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | Kullanılmaz | 0 gün |
| MiMo-V2.5-Pro | Kullanılmaz | 0 gün |
| MiMo-V2.5 | Kullanılmaz | 0 gün |
-| Qwen3.8 Max | Kullanılmaz | 0 gün |
| Qwen3.7 Max | Kullanılmaz | 0 gün |
| Qwen3.7 Plus | Kullanılmaz | 0 gün |
| Qwen3.6 Plus | Kullanılmaz | 0 gün |
| MiniMax M3 | Kullanılmaz | 0 gün |
| MiniMax M2.7 | Kullanılmaz | 0 gün |
| DeepSeek V4 Pro | Kullanılmaz | 0 gün |
-| DeepSeek V4 Flash | Kullanılmaz | 0 gün |
+| DeepSeek V4 Flash | Kullanılır | Anlaşma yok |
| Hy3 | Kullanılmaz | 0 gün |
- **Grok 4.5:** ZDR, durum bilgisi tutan Responses API, Files and Collections ve Batch API dahil olmak üzere saklanan verilere bağlı önemli API özelliklerini devre dışı bırakır. [Daha fazla bilgi](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr).
- **GPT 5.6 Luna:** Tüm API özelliklerinin kullanımı için kötüye kullanım izleme günlükleri oluşturulur ve 30 güne kadar saklanır. [Daha fazla bilgi](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring).
-- **DeepSeek V4 Flash:** ZDR anlaşması aylık olarak yenilenir. Mevcut anlaşma 31 Ağustos 2026 tarihine kadar geçerlidir.
---
diff --git a/packages/web/src/content/docs/tr/zen.mdx b/packages/web/src/content/docs/tr/zen.mdx
index 83f5cfea78..ed5ea7d5fe 100644
--- a/packages/web/src/content/docs/tr/zen.mdx
+++ b/packages/web/src/content/docs/tr/zen.mdx
@@ -86,8 +86,8 @@ Modellerimize aşağıdaki API uç noktaları aracılığıyla da erişebilirsin
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/zen.mdx b/packages/web/src/content/docs/zen.mdx
index 6be3aa7d99..6d57973c55 100644
--- a/packages/web/src/content/docs/zen.mdx
+++ b/packages/web/src/content/docs/zen.mdx
@@ -95,8 +95,8 @@ You can also access our models through the following API endpoints.
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/zh-cn/go.mdx b/packages/web/src/content/docs/zh-cn/go.mdx
index ecf553f33d..806bcd4b2b 100644
--- a/packages/web/src/content/docs/zh-cn/go.mdx
+++ b/packages/web/src/content/docs/zh-cn/go.mdx
@@ -60,7 +60,6 @@ OpenCode Go 的工作方式与 OpenCode 中的其他提供商一样。
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ OpenCode Go 包含以下限制:
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -118,7 +116,6 @@ OpenCode Go 包含以下限制:
- MiMo-V2.5-Pro — 每次请求 790 个输入 token,86,000 个缓存 token,305 个输出 token
- MiniMax M3 — 每次请求 510 个输入 token,56,000 个缓存 token,190 个输出 token
- MiniMax M2.7 — 每次请求 300 个输入 token,55,000 个缓存 token,125 个输出 token
-- Qwen3.8 Max — 每次请求 420 个输入 token,66,000 个缓存 token,200 个输出 token
- Qwen3.7 Max — 每次请求 420 个输入 token,66,000 个缓存 token,200 个输出 token
- Qwen3.7 Plus — 每次请求 500 个输入 token,57,000 个缓存 token,190 个输出 token
- Qwen3.6 Plus — 每次请求 500 个输入 token,57,000 个缓存 token,190 个输出 token
@@ -141,7 +138,6 @@ OpenCode Go 包含以下限制:
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ OpenCode Go 包含以下限制:
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | 不使用 | 0 天 |
| MiMo-V2.5-Pro | 不使用 | 0 天 |
| MiMo-V2.5 | 不使用 | 0 天 |
-| Qwen3.8 Max | 不使用 | 0 天 |
| Qwen3.7 Max | 不使用 | 0 天 |
| Qwen3.7 Plus | 不使用 | 0 天 |
| Qwen3.6 Plus | 不使用 | 0 天 |
| MiniMax M3 | 不使用 | 0 天 |
| MiniMax M2.7 | 不使用 | 0 天 |
| DeepSeek V4 Pro | 不使用 | 0 天 |
-| DeepSeek V4 Flash | 不使用 | 0 天 |
+| DeepSeek V4 Flash | 使用 | 无协议 |
| Hy3 | 不使用 | 0 天 |
- **Grok 4.5:** ZDR 会禁用依赖所存储数据的重要 API 功能,包括有状态的 Responses API、Files and Collections 和 Batch API。[了解更多](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr)。
- **GPT 5.6 Luna:** 所有 API 功能的使用都会生成滥用监控日志,并最多保留 30 天。[了解更多](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring)。
-- **DeepSeek V4 Flash:** ZDR 协议每月续签。当前协议有效期至 2026 年 8 月 31 日。
---
diff --git a/packages/web/src/content/docs/zh-cn/zen.mdx b/packages/web/src/content/docs/zh-cn/zen.mdx
index f4bb9cc502..4838ec4ed5 100644
--- a/packages/web/src/content/docs/zh-cn/zen.mdx
+++ b/packages/web/src/content/docs/zh-cn/zen.mdx
@@ -86,8 +86,8 @@ OpenCode Zen 的工作方式与 OpenCode 中的任何其他提供商相同。
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/packages/web/src/content/docs/zh-tw/go.mdx b/packages/web/src/content/docs/zh-tw/go.mdx
index 53da06c772..2959f63fa2 100644
--- a/packages/web/src/content/docs/zh-tw/go.mdx
+++ b/packages/web/src/content/docs/zh-tw/go.mdx
@@ -60,7 +60,6 @@ OpenCode Go 的運作方式與 OpenCode 中的任何其他供應商相同。
- **MiMo-V2.5-Pro**
- **MiniMax M3**
- **MiniMax M2.7**
-- **Qwen3.8 Max**
- **Qwen3.7 Max**
- **Qwen3.7 Plus**
- **Qwen3.6 Plus**
@@ -97,8 +96,7 @@ OpenCode Go 包含以下限制:
| MiMo-V2.5-Pro | 3,250 | 8,150 | 16,300 |
| MiniMax M3 | 3,200 | 8,000 | 16,000 |
| MiniMax M2.7 | 3,400 | 8,500 | 17,000 |
-| Qwen3.8 Max | 160 | 400 | 810 |
-| Qwen3.7 Max | 340 | 840 | 1,690 |
+| Qwen3.7 Max | 950 | 2,390 | 4,770 |
| Qwen3.7 Plus | 4,300 | 10,800 | 21,600 |
| Qwen3.6 Plus | 3,300 | 8,200 | 16,300 |
| DeepSeek V4 Pro | 3,450 | 8,550 | 17,150 |
@@ -116,7 +114,6 @@ OpenCode Go 包含以下限制:
- DeepSeek V4 Flash — 每次請求 790 個輸入 token、68,000 個快取 token、280 個輸出 token
- MiniMax M3 — 每次請求 510 個輸入 token、56,000 個快取 token、190 個輸出 token
- MiniMax M2.7 — 每次請求 300 個輸入 token、55,000 個快取 token、125 個輸出 token
-- Qwen3.8 Max — 每次請求 420 個輸入 token、66,000 個快取 token、200 個輸出 token
- Qwen3.7 Max — 每次請求 420 個輸入 token、66,000 個快取 token、200 個輸出 token
- Qwen3.7 Plus — 每次請求 500 個輸入 token、57,000 個快取 token、190 個輸出 token
- Qwen3.6 Plus — 每次請求 500 個輸入 token、57,000 個快取 token、190 個輸出 token
@@ -141,7 +138,6 @@ OpenCode Go 包含以下限制:
| MiniMax M3 | $0.30 | $1.20 | $0.06 | - | $60 |
| MiniMax M2.7 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
| MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | $60 |
-| Qwen3.8 Max | $2.00 | $6.00 | $0.25 | $2.50 | $15 |
| Qwen3.7 Max | $2.50 | $7.50 | $0.50 | $3.125 | $60 |
| Qwen3.7 Plus (≤ 256K tokens) | $0.40 | $1.60 | $0.04 | $0.50 | $60 |
| Qwen3.7 Plus (> 256K tokens) | $1.20 | $4.80 | $0.12 | $1.50 | $60 |
@@ -199,7 +195,6 @@ OpenCode Go 包含以下限制:
| MiniMax M3 | minimax-m3 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.7 | minimax-m2.7 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
-| Qwen3.8 Max | qwen3.8-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/go/v1/messages` | `@ai-sdk/anthropic` |
@@ -232,19 +227,17 @@ https://opencode.ai/zen/go/v1/models
| Kimi K2.6 | 不使用 | 0 天 |
| MiMo-V2.5-Pro | 不使用 | 0 天 |
| MiMo-V2.5 | 不使用 | 0 天 |
-| Qwen3.8 Max | 不使用 | 0 天 |
| Qwen3.7 Max | 不使用 | 0 天 |
| Qwen3.7 Plus | 不使用 | 0 天 |
| Qwen3.6 Plus | 不使用 | 0 天 |
| MiniMax M3 | 不使用 | 0 天 |
| MiniMax M2.7 | 不使用 | 0 天 |
| DeepSeek V4 Pro | 不使用 | 0 天 |
-| DeepSeek V4 Flash | 不使用 | 0 天 |
+| DeepSeek V4 Flash | 使用 | 無協議 |
| Hy3 | 不使用 | 0 天 |
- **Grok 4.5:** ZDR 會停用依賴儲存資料的重要 API 功能,包括具狀態的 Responses API、Files and Collections 與 Batch API。[了解更多](https://docs.x.ai/developers/faq/security#what-is-zero-data-retention-zdr)。
- **GPT 5.6 Luna:** 所有 API 功能的使用都會產生濫用監控日誌,並保留最多 30 天。[了解更多](https://developers.openai.com/api/docs/guides/your-data#data-retention-controls-for-abuse-monitoring)。
-- **DeepSeek V4 Flash:** ZDR 協議每月續簽。目前的協議有效至 2026 年 8 月 31 日。
---
diff --git a/packages/web/src/content/docs/zh-tw/zen.mdx b/packages/web/src/content/docs/zh-tw/zen.mdx
index 60b87c88df..54a8fcc92b 100644
--- a/packages/web/src/content/docs/zh-tw/zen.mdx
+++ b/packages/web/src/content/docs/zh-tw/zen.mdx
@@ -90,8 +90,8 @@ OpenCode Zen 的運作方式和 OpenCode 中的其他供應商一樣。
| Gemini 3.5 Flash Lite | gemini-3.5-flash-lite | `https://opencode.ai/zen/v1/models/gemini-3.5-flash-lite` | `@ai-sdk/google` |
| Gemini 3.1 Pro | gemini-3.1-pro | `https://opencode.ai/zen/v1/models/gemini-3.1-pro` | `@ai-sdk/google` |
| Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` |
-| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
-| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/responses` | `@ai-sdk/openai` |
+| Grok 4.5 | grok-4.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
+| Grok Build 0.1 | grok-build-0.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` |
| Qwen3.7 Max | qwen3.7-max | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.7 Plus | qwen3.7-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
| Qwen3.6 Plus | qwen3.6-plus | `https://opencode.ai/zen/v1/messages` | `@ai-sdk/anthropic` |
diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json
index 4c0e903459..15943599b3 100644
--- a/sdks/vscode/package.json
+++ b/sdks/vscode/package.json
@@ -2,7 +2,7 @@
"name": "opencode",
"displayName": "opencode",
"description": "opencode for VS Code",
- "version": "1.18.11",
+ "version": "1.18.10",
"publisher": "sst-dev",
"repository": {
"type": "git",