diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 15f865b742..1c41a66faa 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -339,8 +339,7 @@ jobs: env: OPENCODE_CHANNEL: ${{ (github.ref_name == 'beta' && 'beta') || 'prod' }} GH_TOKEN: ${{ steps.committer.outputs.token }} - CSC_LINK: ${{ secrets.APPLE_CERTIFICATE }} - CSC_KEY_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }} + CSC_KEYCHAIN: build.keychain 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 4de04ab24d..e905ada8c5 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@corvu/drawer": "catalog:", "@dnd-kit/abstract": "0.5.0", @@ -96,7 +96,7 @@ }, "packages/cli": { "name": "@opencode-ai/cli", - "version": "1.18.10", + "version": "1.18.11", "bin": { "lildax": "./bin/lildax.cjs", }, @@ -144,7 +144,7 @@ }, "packages/codemode": { "name": "@opencode-ai/codemode", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "acorn": "8.15.0", "effect": "catalog:", @@ -158,7 +158,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.18.10", + "version": "1.18.11", "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.10", + "version": "1.18.11", "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.10", + "version": "1.18.11", "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.10", + "version": "1.18.11", "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.10", + "version": "1.18.11", "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.10", + "version": "1.18.11", "bin": { "opencode": "./bin/opencode", }, @@ -381,9 +381,10 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@zip.js/zip.js": "2.7.62", + "drizzle-orm": "catalog:", "effect": "catalog:", "electron-context-menu": "4.1.2", "electron-log": "^5", @@ -434,7 +435,7 @@ }, "packages/effect-drizzle-sqlite": { "name": "@opencode-ai/effect-drizzle-sqlite", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "drizzle-orm": "catalog:", "effect": "catalog:", @@ -448,7 +449,7 @@ }, "packages/effect-sqlite-node": { "name": "@opencode-ai/effect-sqlite-node", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "effect": "catalog:", }, @@ -460,7 +461,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@hono/standard-validator": "catalog:", "@opencode-ai/core": "workspace:*", @@ -492,7 +493,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -508,7 +509,7 @@ }, "packages/http-recorder": { "name": "@opencode-ai/http-recorder", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@effect/platform-node": "4.0.0-beta.83", "@effect/platform-node-shared": "4.0.0-beta.83", @@ -539,7 +540,7 @@ }, "packages/llm": { "name": "@opencode-ai/llm", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@opencode-ai/schema": "workspace:*", "@smithy/eventstream-codec": "4.2.14", @@ -558,7 +559,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.18.10", + "version": "1.18.11", "bin": { "opencode": "./bin/opencode", }, @@ -689,7 +690,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@ai-sdk/provider": "3.0.8", "@opencode-ai/sdk": "workspace:*", @@ -765,7 +766,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "cross-spawn": "catalog:", }, @@ -780,7 +781,7 @@ }, "packages/server": { "name": "@opencode-ai/server", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/protocol": "workspace:*", @@ -795,7 +796,7 @@ }, "packages/session-ui": { "name": "@opencode-ai/session-ui", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/client": "file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz", @@ -839,7 +840,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -852,7 +853,7 @@ }, "packages/stats/app": { "name": "@opencode-ai/stats-app", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@ibm/plex": "6.4.1", "@kobalte/core": "catalog:", @@ -886,7 +887,7 @@ }, "packages/stats/core": { "name": "@opencode-ai/stats-core", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@aws-sdk/client-athena": "3.933.0", "@planetscale/database": "1.19.0", @@ -905,7 +906,7 @@ }, "packages/stats/server": { "name": "@opencode-ai/stats-server", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@aws-sdk/client-firehose": "3.933.0", "@effect/platform-node": "catalog:", @@ -947,7 +948,7 @@ }, "packages/tui": { "name": "@opencode-ai/tui", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/plugin": "workspace:*", @@ -974,7 +975,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@kobalte/core": "catalog:", "@pierre/diffs": "catalog:", @@ -1026,7 +1027,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.18.10", + "version": "1.18.11", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/nix/hashes.json b/nix/hashes.json index 2fafb82c44..25f0e76812 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-SiJd6uXrL/MqqFGN/uUcHh0Wzdlafnpx++VZa5gUCoE=", - "aarch64-linux": "sha256-pKcT34NYIHVasraRTx0ASTzyuFuIzBTxXg6+KSKvTps=", - "aarch64-darwin": "sha256-hzrym0KpiyYAv80eT/DjcSIJWYBUq4QDgDf6Wtot7jU=", - "x86_64-darwin": "sha256-Or5dSTdajUwij0XpovXSXjJ0LmRUcpcW5TJ4q4B0k0A=" + "x86_64-linux": "sha256-a7NyYa9vRUEqDfZNDPXXmFO58RDEgioyuGSl5CPBvxo=", + "aarch64-linux": "sha256-l4OJtSEllHvRhktjcaJYwkXBSaJvsIoyoLusbZfYMcM=", + "aarch64-darwin": "sha256-IIl0BQGs1/HLFh0auiQjiwfSQ2nfHcK2G2BAphYW59c=", + "x86_64-darwin": "sha256-vVeuPyd4ZIRYrHouphTuEb4rkRZLKKTAHe840jNh9rU=" } } diff --git a/packages/app/e2e/regression/project-picker-recent-search.spec.ts b/packages/app/e2e/regression/project-picker-recent-search.spec.ts new file mode 100644 index 0000000000..2cdb0b4a03 --- /dev/null +++ b/packages/app/e2e/regression/project-picker-recent-search.spec.ts @@ -0,0 +1,60 @@ +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 e6e95e35ff..2dd4a05d86 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.18.10", + "version": "1.18.11", "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 96bcedb9db..fc248d821e 100644 --- a/packages/app/src/components/dialog-select-directory.tsx +++ b/packages/app/src/components/dialog-select-directory.tsx @@ -18,6 +18,8 @@ interface DialogSelectDirectoryProps { server: ServerConnection.Any } +const RECENT_PROJECT_LIMIT = 5 + type Row = { absolute: string search: string @@ -102,7 +104,6 @@ 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) @@ -116,7 +117,10 @@ export function DialogSelectDirectory(props: DialogSelectDirectoryProps) { const items = async (value: string) => { const results = await directories(value) const directoryRows = results.map((absolute) => toRow(absolute, home(), "folders")) - return uniqueRows([...recentProjects(), ...directoryRows]) + // 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]) } 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 2d6a5e98d6..96b99aaf4a 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,6 +377,7 @@ 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 7923e18ee2..08c1ee3489 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 9568b17d19..6f3ef57c66 100644 --- a/packages/app/src/components/prompt-input/attachments.ts +++ b/packages/app/src/components/prompt-input/attachments.ts @@ -3,28 +3,13 @@ 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 } @@ -36,6 +21,7 @@ type PromptAttachmentsCoreInput = { warn?: () => void readClipboardImage?: () => Promise getPathForFile?: (file: File) => string + draftStore?: DraftStore } export type PromptAttachmentsInput = { @@ -65,16 +51,13 @@ 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, - dataUrl: url, + blob: input.draftStore ? await input.draftStore.putBlob(file) : await createBlobReference(file), } target.prompt.set([...target.prompt.current(), attachment], target.cursor) return true @@ -166,8 +149,10 @@ 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 7f0fea2bfe..a1e3448b31 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: ImageAttachmentPart[] + images: (Omit & { dataUrl: string })[] 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 b64636f3c0..3858b8b9bc 100644 --- a/packages/app/src/components/prompt-input/history-store.ts +++ b/packages/app/src/components/prompt-input/history-store.ts @@ -1,7 +1,13 @@ import { createStore, type SetStoreFunction, type Store } from "solid-js/store" import type { Prompt } from "@/context/prompt" import { Persist, persisted } from "@/utils/persist" -import { prependHistoryEntry, type PromptHistoryComment, type PromptHistoryStoredEntry } from "./history" +import { + clonePromptHistoryComments, + clonePromptParts, + prependHistoryEntry, + type PromptHistoryComment, + type PromptHistoryStoredEntry, +} from "./history" export type PromptInputHistory = { entries: (mode: "normal" | "shell") => PromptHistoryStoredEntry[] @@ -35,13 +41,23 @@ export function createPromptInputHistory(): PromptInputHistory { } export function createPersistedPromptInputHistory() { - const [normal, setNormal] = persisted( - Persist.global("prompt-history", ["prompt-history.v1"]), + const [normal, setNormal, normalInit] = persisted( + Persist.prompt(Persist.global("prompt-history", ["prompt-history.v1"])), createStore({ entries: [] }), ) - const [shell, setShell] = persisted( - Persist.global("prompt-history-shell", ["prompt-history-shell.v1"]), + const [shell, setShell, shellInit] = persisted( + Persist.prompt(Persist.global("prompt-history-shell", ["prompt-history-shell.v1"])), createStore({ entries: [] }), ) - return createPromptInputHistoryStore(normal, setNormal, shell, setShell) + 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)) + }, + } } diff --git a/packages/app/src/components/prompt-input/history.test.ts b/packages/app/src/components/prompt-input/history.test.ts index 5e9c2c66ea..94f24ce935 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", dataUrl: "data:image/png;base64,abc" }, + { type: "image", id: "1", filename: "img.png", mime: "image/png", blob: { id: "blob", url: "blob:test" } }, ] 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 3a0cc3e4dd..ecc38db888 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 } > {attachment.filename} props.onOpen(attachment)} diff --git a/packages/app/src/components/prompt-input/submit.ts b/packages/app/src/components/prompt-input/submit.ts index 051bf4d06c..c82c3a4399 100644 --- a/packages/app/src/components/prompt-input/submit.ts +++ b/packages/app/src/components/prompt-input/submit.ts @@ -22,6 +22,7 @@ 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 @@ -95,10 +96,12 @@ export async function sendFollowupDraft(input: FollowupSendInput) { providerID: input.draft.model.providerID, variant: input.draft.variant, }, - files: images.map((attachment) => ({ - uri: attachment.dataUrl, - name: attachment.filename, - })), + files: await Promise.all( + images.map(async (attachment) => ({ + uri: await blobDataUrl(attachment.blob, attachment.mime), + name: attachment.filename, + })), + ), }) return true } catch (err) { @@ -108,10 +111,16 @@ 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, + images: encodedImages, text, sessionID: input.draft.sessionID, messageID, @@ -516,10 +525,12 @@ export function createPromptSubmit(input: PromptSubmitInput) { arguments: args.join(" "), agent, model: { id: model.modelID, providerID: model.providerID, variant }, - files: images.map((attachment) => ({ - uri: attachment.dataUrl, - name: attachment.filename, - })), + files: await Promise.all( + images.map(async (attachment) => ({ + uri: await blobDataUrl(attachment.blob, attachment.mime), + 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 71986dd3c4..a95706a3db 100644 --- a/packages/app/src/context/global-sync/bootstrap.test.ts +++ b/packages/app/src/context/global-sync/bootstrap.test.ts @@ -8,6 +8,7 @@ import { bootstrapDirectory, loadAgentsQuery, loadCommands, + loadGlobalConfigQuery, loadPathQuery, loadProjectsQuery, loadProvidersQuery, @@ -76,6 +77,7 @@ 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() @@ -91,7 +93,12 @@ describe("bootstrapDirectory", () => { }, sdk: { app: { agents: async () => ({ data: [{ name: "build", mode: "primary" }] }) }, - config: { get: async () => ({ data: {} }) }, + config: { + get: async () => { + legacyConfigReads.push("directory") + return { data: {} } + }, + }, session: { status: async () => ({ data: {} }) }, vcs: { get: async () => ({ data: undefined }) }, command: { @@ -134,8 +141,88 @@ 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 39221d551f..0f3e473816 100644 --- a/packages/app/src/context/global-sync/bootstrap.ts +++ b/packages/app/src/context/global-sync/bootstrap.ts @@ -105,10 +105,13 @@ function showErrors(input: { }) } -export const loadGlobalConfigQuery = (scope: ServerScope, sdk: OpencodeClient) => +export const loadGlobalConfigQuery = (scope: ServerScope, sdk: OpencodeClient, protocol?: Promise) => queryOptions({ queryKey: [scope, "config"], - queryFn: () => retry(() => sdk.global.config.get().then((x) => x.data!)), + queryFn: async () => { + if ((await protocol) !== "v1") return {} + return retry(() => sdk.global.config.get().then((x) => x.data!)) + }, }) type ProjectApi = { @@ -149,7 +152,7 @@ export async function bootstrapGlobal(input: { queryClient: QueryClient }) { const slow = [ - () => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.scope, input.serverSDK)), + () => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.scope, input.serverSDK, input.protocol)), () => input.queryClient.fetchQuery( loadProvidersQuery(input.scope, null, input.serverAPI, input.serverSDK, input.protocol), @@ -376,7 +379,10 @@ 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(() => input.sdk.config.get().then((x) => input.setStore("config", reconcile(x.data!, { merge: false })))), + retry(async () => { + if ((await input.protocol) !== "v1") return + return 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 08686361c5..0408b233ff 100644 --- a/packages/app/src/context/platform.tsx +++ b/packages/app/src/context/platform.tsx @@ -5,6 +5,7 @@ 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 } @@ -64,6 +65,9 @@ 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 73196289e2..ea639a5bdd 100644 --- a/packages/app/src/context/prompt-state.ts +++ b/packages/app/src/context/prompt-state.ts @@ -5,6 +5,7 @@ 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 @@ -37,7 +38,7 @@ export interface ImageAttachmentPart { filename: string sourcePath?: string mime: string - dataUrl: string + blob: BlobReference } export type ContentPart = TextPart | FileAttachmentPart | AgentPart | ImageAttachmentPart @@ -168,9 +169,9 @@ function createPromptActions(setStore: SetStoreFunction) { } function promptTarget(serverScope: ServerScope, scope: PromptScope) { - if ("draftID" in scope) return Persist.draft(scope.draftID, "prompt") + if ("draftID" in scope) return Persist.prompt(Persist.draft(scope.draftID, "prompt")) const legacy = `${scope.dir}/prompt${scope.id ? "/" + scope.id : ""}.v2` - return Persist.serverScoped(serverScope, scope.dir, scope.id, "prompt", [legacy]) + return Persist.prompt(Persist.serverScoped(serverScope, scope.dir, scope.id, "prompt", [legacy])) } function promptStore(initial?: InitialPrompt): PromptStore { @@ -245,7 +246,7 @@ export function createPromptSession(serverScope: ServerScope, scope: PromptScope } export function createDraftPromptSession(draftID: string, initial?: InitialPrompt) { - return createPersistedPrompt(Persist.draft(draftID, "prompt"), initial) + return createPersistedPrompt(Persist.prompt(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 196cda8479..13a0b74bc6 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()), + globalConfig: () => loadGlobalConfigQuery(scope, serverSDK(), protocol), 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 e4d50ac161..b6608e8681 100644 --- a/packages/app/src/context/tabs.tsx +++ b/packages/app/src/context/tabs.tsx @@ -101,7 +101,10 @@ export const { use: useTabs, provider: TabsProvider } = createSimpleContext({ } const removeDraftPersisted = (draftID: string) => { - for (const key of draftPersistedKeys()) removePersisted(Persist.draft(draftID, key), platform) + for (const key of draftPersistedKeys()) { + const target = Persist.draft(draftID, key) + removePersisted(key === "prompt" ? Persist.prompt(target) : target, platform) + } } const removeInfo = (key: string) => { diff --git a/packages/app/src/entry.tsx b/packages/app/src/entry.tsx index 6823d1c6d7..9b71d6567e 100644 --- a/packages/app/src/entry.tsx +++ b/packages/app/src/entry.tsx @@ -4,6 +4,7 @@ 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" @@ -116,6 +117,7 @@ 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 2267ebf081..8d36086d9f 100644 --- a/packages/app/src/index.ts +++ b/packages/app/src/index.ts @@ -27,3 +27,4 @@ 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 32a1d5f57c..a5952a5e66 100644 --- a/packages/app/src/pages/session/timeline/rows-current.test.ts +++ b/packages/app/src/pages/session/timeline/rows-current.test.ts @@ -167,4 +167,41 @@ 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 25a5113344..879646e86a 100644 --- a/packages/app/src/pages/session/timeline/rows.ts +++ b/packages/app/src/pages/session/timeline/rows.ts @@ -116,7 +116,8 @@ 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 error = assistantMessages.find((m) => m.error && m.error.name !== "MessageAbortedError")?.error + const latestError = assistantMessages.at(-1)?.error + const error = latestError?.name === "MessageAbortedError" ? undefined : latestError 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 new file mode 100644 index 0000000000..cd0895f52c --- /dev/null +++ b/packages/app/src/utils/draft-store.ts @@ -0,0 +1,171 @@ +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 a2daae4866..a7742c399e 100644 --- a/packages/app/src/utils/persist.ts +++ b/packages/app/src/utils/persist.ts @@ -15,6 +15,7 @@ type PersistedWithReady = [ ] type PersistTarget = { + draft?: boolean storage?: string scope?: "window" legacyStorageNames?: string[] @@ -295,6 +296,14 @@ 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 @@ -513,6 +522,9 @@ 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 { @@ -526,9 +538,12 @@ function resolveTarget(target: PersistTarget, platform: Platform): PersistTarget } export function removePersisted( - target: { storage?: string; legacyStorageNames?: string[]; key: string }, + target: { draft?: boolean; 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) { @@ -561,8 +576,17 @@ 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) @@ -577,7 +601,7 @@ export function persisted( const legacyStorageNames = config.legacyStorageNames ?? [] const storage = (() => { - if (!isDesktop) { + if (!isDesktop && !draft) { const current = currentStorage as SyncStorage const legacyStore = legacyStorage as SyncStorage const legacyStores = legacyStorageNames.map(localStorageWithPrefix) @@ -609,15 +633,26 @@ export function persisted( const current = currentStorage as AsyncStorage const legacyStore = legacyStorage as AsyncStorage | undefined - const legacyStores = legacyStorageNames - .map((name) => platform.storage?.(name) 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))), + ] .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 - return migrateLegacyAsync({ + const migrated = await migrateLegacyAsync({ current, legacyStore, stores: legacyStores, @@ -626,8 +661,15 @@ 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 1ecaf02c97..8b86d43b90 100644 --- a/packages/app/src/utils/prompt.test.ts +++ b/packages/app/src/utils/prompt.test.ts @@ -37,8 +37,18 @@ 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", dataUrl: "data:image/png;base64,AAA" }, - { type: "image", filename: "b.pdf", mime: "application/pdf", dataUrl: "data:application/pdf;base64,BBB" }, + { + 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) }), + }, ]) }) }) diff --git a/packages/app/src/utils/prompt.ts b/packages/app/src/utils/prompt.ts index 35aec0071a..67d32086bb 100644 --- a/packages/app/src/utils/prompt.ts +++ b/packages/app/src/utils/prompt.ts @@ -1,5 +1,6 @@ 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 = | { @@ -107,7 +108,7 @@ export function extractPromptFromParts(parts: Part[], opts?: { directory?: strin id: filePart.id, filename: filePart.filename ?? attachmentName, mime: filePart.mime, - dataUrl: filePart.url, + blob: createLegacyBlobReference(filePart.url), }) } } diff --git a/packages/app/test-browser/prompt-persistence.test.ts b/packages/app/test-browser/prompt-persistence.test.ts index a7b08078d7..f3d8f8ae4f 100644 --- a/packages/app/test-browser/prompt-persistence.test.ts +++ b/packages/app/test-browser/prompt-persistence.test.ts @@ -2,6 +2,7 @@ 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 @@ -30,7 +31,7 @@ beforeAll(async () => { }), })) mock.module("@/context/platform", () => ({ - usePlatform: () => ({ platform: "desktop", storage: () => storage }), + usePlatform: () => ({ platform: "desktop", storage: () => storage, draftStore: storage }), })) Prompt = await import("@/context/prompt") @@ -69,3 +70,50 @@ 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 46a372229b..be5d853de0 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.10", + "version": "1.18.11", "type": "module", "license": "MIT", "bin": { diff --git a/packages/codemode/package.json b/packages/codemode/package.json index e0c89ec26e..1641518483 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.10", + "version": "1.18.11", "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 f27b89305f..5023021661 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.10", + "version": "1.18.11", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/app/src/i18n/ar.ts b/packages/console/app/src/i18n/ar.ts index 6b84df8e0e..dd03a553f5 100644 --- a/packages/console/app/src/i18n/ar.ts +++ b/packages/console/app/src/i18n/ar.ts @@ -347,6 +347,7 @@ 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 10c171d0a8..dac06753e9 100644 --- a/packages/console/app/src/i18n/br.ts +++ b/packages/console/app/src/i18n/br.ts @@ -354,6 +354,8 @@ 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 ab204d8aac..4e3d230f90 100644 --- a/packages/console/app/src/i18n/da.ts +++ b/packages/console/app/src/i18n/da.ts @@ -351,6 +351,8 @@ 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 9a9f4dcbe1..61184358da 100644 --- a/packages/console/app/src/i18n/de.ts +++ b/packages/console/app/src/i18n/de.ts @@ -353,6 +353,8 @@ 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 dcb2b4431d..813473c367 100644 --- a/packages/console/app/src/i18n/en.ts +++ b/packages/console/app/src/i18n/en.ts @@ -348,6 +348,8 @@ 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 506aa62950..be5c24685c 100644 --- a/packages/console/app/src/i18n/es.ts +++ b/packages/console/app/src/i18n/es.ts @@ -354,6 +354,8 @@ 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 f0238f2d08..37bf2d5eb3 100644 --- a/packages/console/app/src/i18n/fr.ts +++ b/packages/console/app/src/i18n/fr.ts @@ -355,6 +355,8 @@ 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 548d4d479f..501d012333 100644 --- a/packages/console/app/src/i18n/it.ts +++ b/packages/console/app/src/i18n/it.ts @@ -350,6 +350,8 @@ 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 fd4224d598..e8f8fa5661 100644 --- a/packages/console/app/src/i18n/ja.ts +++ b/packages/console/app/src/i18n/ja.ts @@ -349,6 +349,7 @@ 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 9b6a0efbd4..ab76958985 100644 --- a/packages/console/app/src/i18n/ko.ts +++ b/packages/console/app/src/i18n/ko.ts @@ -345,6 +345,7 @@ 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 e3ff8db3cf..5e7e025032 100644 --- a/packages/console/app/src/i18n/no.ts +++ b/packages/console/app/src/i18n/no.ts @@ -351,6 +351,8 @@ 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 874a90e5b0..2aa536cd82 100644 --- a/packages/console/app/src/i18n/pl.ts +++ b/packages/console/app/src/i18n/pl.ts @@ -352,6 +352,7 @@ 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 7cafbd687d..330713cd19 100644 --- a/packages/console/app/src/i18n/ru.ts +++ b/packages/console/app/src/i18n/ru.ts @@ -356,6 +356,8 @@ 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 81ad9a9f37..d3ff91e97a 100644 --- a/packages/console/app/src/i18n/th.ts +++ b/packages/console/app/src/i18n/th.ts @@ -348,6 +348,7 @@ 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 701be9a5ae..5d0d2819dd 100644 --- a/packages/console/app/src/i18n/tr.ts +++ b/packages/console/app/src/i18n/tr.ts @@ -354,6 +354,8 @@ 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 0ee26f5f59..48a0dbe787 100644 --- a/packages/console/app/src/i18n/uk.ts +++ b/packages/console/app/src/i18n/uk.ts @@ -352,6 +352,7 @@ 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 d4a59900fc..78f2081aeb 100644 --- a/packages/console/app/src/i18n/zh.ts +++ b/packages/console/app/src/i18n/zh.ts @@ -333,6 +333,7 @@ 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 635ad91d2f..190a927d3f 100644 --- a/packages/console/app/src/i18n/zht.ts +++ b/packages/console/app/src/i18n/zht.ts @@ -333,6 +333,7 @@ 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 710650d4dc..17c78f214d 100644 --- a/packages/console/app/src/routes/go/index.tsx +++ b/packages/console/app/src/routes/go/index.tsx @@ -32,13 +32,14 @@ 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.used", retention: "go.faq.a5.noAgreement" }, + { name: "DeepSeek V4 Flash", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" }, { name: "Hy3", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" }, ] as const @@ -67,6 +68,7 @@ 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" }, @@ -505,6 +507,9 @@ export default function Home() { .

+

+ DeepSeek V4 Flash: {i18n.t("go.faq.a5.deepseekRetention")} +

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 331c13e147..da1b053a35 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,6 +313,7 @@ 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 404657d443..1bc2ce1f21 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: outputTokens + reasoningTokens, reasoningTokens, cacheReadTokens, cacheWrite5mTokens: undefined, diff --git a/packages/console/core/migrations/20260803084635_married_misty_knight/migration.sql b/packages/console/core/migrations/20260803084635_married_misty_knight/migration.sql new file mode 100644 index 0000000000..2ef8df67a6 --- /dev/null +++ b/packages/console/core/migrations/20260803084635_married_misty_knight/migration.sql @@ -0,0 +1,2 @@ +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 new file mode 100644 index 0000000000..239f3266f2 --- /dev/null +++ b/packages/console/core/migrations/20260803084635_married_misty_knight/snapshot.json @@ -0,0 +1,3167 @@ +{ + "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 63ba0a50f2..ea543f40db 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.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/core/src/referral.ts b/packages/console/core/src/referral.ts index 7d683f8d88..7fac9e1b98 100644 --- a/packages/console/core/src/referral.ts +++ b/packages/console/core/src/referral.ts @@ -59,30 +59,7 @@ export namespace Referral { const accountID = Actor.account() const code = await ensureCode(workspaceID) const rows = await Database.use(async (tx) => { - 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), - ), - ), + const [invites, inviteeReferral] = await Promise.all([ tx .select({ id: ReferralTable.id, inviteeEmail: AuthTable.subject, timeCreated: ReferralTable.timeCreated }) .from(ReferralTable) @@ -106,19 +83,20 @@ 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 915646cf3d..b177858f36 100644 --- a/packages/console/core/src/schema/billing.sql.ts +++ b/packages/console/core/src/schema/billing.sql.ts @@ -53,6 +53,7 @@ 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 9850c92457..be2499ee11 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, mysqlTable, primaryKey, uniqueIndex, varchar } from "drizzle-orm/mysql-core" +import { bigint, index, mysqlTable, primaryKey, uniqueIndex, varchar } from "drizzle-orm/mysql-core" import { timestamps, ulid, utc, workspaceColumns } from "../drizzle/types" import { workspaceIndexes } from "./workspace.sql" @@ -31,5 +31,8 @@ export const ReferralRewardTable = mysqlTable( amount: bigint("amount", { mode: "number" }).notNull(), timeApplied: utc("time_applied"), }, - (table) => [primaryKey({ columns: [table.workspaceID, table.referralID] })], + (table) => [ + primaryKey({ columns: [table.workspaceID, table.referralID] }), + index("referral_id").on(table.referralID), + ], ) diff --git a/packages/console/function/package.json b/packages/console/function/package.json index 52581a8c93..4aa9b01170 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.10", + "version": "1.18.11", "$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 f54268c9c8..071ca199d6 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.10", + "version": "1.18.11", "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 6b6a65b6e6..a69bbe4268 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.10", + "version": "1.18.11", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/core/package.json b/packages/core/package.json index a8a5041e73..babaec7d6c 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.10", + "version": "1.18.11", "name": "@opencode-ai/core", "type": "module", "license": "MIT", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index a407d3d192..6776591b3e 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.18.10", + "version": "1.18.11", "type": "module", "license": "MIT", "homepage": "https://opencode.ai", @@ -30,7 +30,8 @@ "electron-log": "^5", "electron-store": "11.0.2", "electron-updater": "6.8.9", - "electron-window-state": "^5.0.3" + "electron-window-state": "^5.0.3", + "drizzle-orm": "catalog:" }, "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 new file mode 100644 index 0000000000..95d4e7aa80 --- /dev/null +++ b/packages/desktop/src/main/draft-store.test.ts @@ -0,0 +1,16 @@ +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 new file mode 100644 index 0000000000..839eff26af --- /dev/null +++ b/packages/desktop/src/main/draft-store.ts @@ -0,0 +1,82 @@ +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 556fd26d96..e920b60257 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.exit(0) + app.quit() }) } @@ -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.exit(0)) + void stopSidecars().finally(() => app.quit()) }) } diff --git a/packages/desktop/src/main/ipc.ts b/packages/desktop/src/main/ipc.ts index f3208a70f3..bd7a3a7554 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 } from "node:path" +import { basename, join } 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,6 +21,7 @@ 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 @@ -51,8 +52,12 @@ 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()) @@ -123,6 +128,14 @@ 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 270ff4e576..6b8bd4dfa7 100644 --- a/packages/desktop/src/preload/index.ts +++ b/packages/desktop/src/preload/index.ts @@ -73,6 +73,11 @@ 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 3542a11191..fbf58f1fd6 100644 --- a/packages/desktop/src/preload/types.ts +++ b/packages/desktop/src/preload/types.ts @@ -63,6 +63,11 @@ 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 244b5eb405..e1ff8fbfc2 100644 --- a/packages/desktop/src/renderer/index.tsx +++ b/packages/desktop/src/renderer/index.tsx @@ -9,6 +9,7 @@ import { type Locale, type Platform, PlatformProvider, + createDraftStore, ServerConnection, useCommand, useWslServers, @@ -226,6 +227,13 @@ 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 9577e7a463..c5a637c4e3 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.10", + "version": "1.18.11", "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 7c084da87b..8274aee610 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.10", + "version": "1.18.11", "name": "@opencode-ai/effect-sqlite-node", "type": "module", "license": "MIT", diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 117d2220ad..1ca75a6381 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.18.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/function/package.json b/packages/function/package.json index f8e1ee3d86..096c350399 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.18.10", + "version": "1.18.11", "$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 56224a41c7..99147a95a3 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.10", + "version": "1.18.11", "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 d575867f1c..908852b3cc 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.10", + "version": "1.18.11", "name": "@opencode-ai/llm", "type": "module", "license": "MIT", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 84f03d88ab..946102e5e2 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.10", + "version": "1.18.11", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 33b6d2b0dc..b95531d62e 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.10", + "version": "1.18.11", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 68313859b6..aa86ed50b5 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.10", + "version": "1.18.11", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index fcfa76143e..b0094607fc 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.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/session-ui/package.json b/packages/session-ui/package.json index 834b899b4c..dddef7f277 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.10", + "version": "1.18.11", "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 afa97a7f3e..89f38ec4a3 100644 --- a/packages/session-ui/src/v2/components/prompt-input/attachments.ts +++ b/packages/session-ui/src/v2/components/prompt-input/attachments.ts @@ -78,6 +78,7 @@ export type PromptInputV2AttachmentConfig = { onError: (error: unknown) => void readClipboardImage?: () => Promise getPathForFile?: (file: File) => string + store?: (file: File) => Promise<{ id: string; url: string }> } export function createPromptInputV2Attachments( @@ -102,8 +103,7 @@ export function createPromptInputV2Attachments( if (toast) input.warn() return false } - const url = await dataUrl(file, mime) - if (!url) return false + const blob = input.store ? await input.store(file) : await blobReference(file) 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.dataUrl === url && + part.blob.id === blob.id && (sourcePath ? part.sourcePath === sourcePath : !part.sourcePath && (clipboard || part.filename === file.name)), @@ -127,7 +127,7 @@ export function createPromptInputV2Attachments( filename: file.name, sourcePath, mime, - dataUrl: url, + blob, } target.prompt.set([...target.prompt.current(), attachment], target.cursor) return true @@ -219,20 +219,14 @@ export function createPromptInputV2Attachments( } } -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"]) + +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) } +} 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 0989e2ef65..d29fd4df23 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: { } > {attachment.filename} 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 525c264097..6c535b0284 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", - dataUrl: "data:text/markdown;base64,IyBSZXF1aXJlbWVudHM=", + blob: { id: "requirements", url: "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, - dataUrl: `data:${mime};base64,`, + blob: { id: filename, url: `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 a58428d9c1..768a222450 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", - dataUrl: "data:text/plain;base64,", + blob: { id: "a", url: "blob:a" }, }, ], cursor: 3, @@ -50,7 +50,7 @@ describe("prompt input v2 store", () => { id: "attachment-1", filename: "notes.txt", mime: "text/plain", - dataUrl: "data:text/plain;base64,", + blob: { id: "a", url: "blob:a" }, }, ]) 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 a2630a5ea6..c6b47a92ce 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 - dataUrl: string + blob: { id: string; url: string } } export type PromptInputV2Prompt = ( diff --git a/packages/slack/package.json b/packages/slack/package.json index 20f1ce0598..46d7d185e3 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.18.10", + "version": "1.18.11", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/stats/app/package.json b/packages/stats/app/package.json index 3a19ff5aad..a04d6761a7 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.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/stats/core/package.json b/packages/stats/core/package.json index c139702674..e02d8e1314 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.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/stats/server/package.json b/packages/stats/server/package.json index efa68e21dc..9eb222ec80 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.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/tui/package.json b/packages/tui/package.json index a96b6a7088..e1bc700ac7 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.10", + "version": "1.18.11", "private": true, "type": "module", "license": "MIT", diff --git a/packages/ui/package.json b/packages/ui/package.json index 36cd5ad027..957f3151e9 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.18.10", + "version": "1.18.11", "type": "module", "license": "MIT", "repository": { diff --git a/packages/web/package.json b/packages/web/package.json index 260ca51941..c9637aee6b 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.10", + "version": "1.18.11", "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 f885517639..b0be0b6157 100644 --- a/packages/web/src/content/docs/ar/go.mdx +++ b/packages/web/src/content/docs/ar/go.mdx @@ -60,6 +60,7 @@ OpenCode Go هو اشتراك منخفض التكلفة — **$5 للشهر ال - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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 لكل طلب @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | مستخدَمة | لا توجد اتفاقية | +| DeepSeek V4 Flash | غير مستخدَمة | 0 أيام | | 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 83aeb104c5..0cc94de6ef 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/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` | +| 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` | | 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 a5166f7528..634b3a8685 100644 --- a/packages/web/src/content/docs/bs/go.mdx +++ b/packages/web/src/content/docs/bs/go.mdx @@ -70,6 +70,7 @@ 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** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +126,7 @@ 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 @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Koristi se | Nema sporazuma | +| DeepSeek V4 Flash | Ne koristi se | 0 dana | | 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 82f85e9198..17cf73581b 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/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` | +| 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` | | 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 3ea1bacc19..5aabcc7c43 100644 --- a/packages/web/src/content/docs/da/go.mdx +++ b/packages/web/src/content/docs/da/go.mdx @@ -70,6 +70,7 @@ 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** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +126,7 @@ 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 @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Brugt | Ingen aftale | +| DeepSeek V4 Flash | Ikke brugt | 0 dage | | 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 c7545e170b..e200e14e60 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/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` | +| 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` | | 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 061b3840eb..73a11d454f 100644 --- a/packages/web/src/content/docs/de/go.mdx +++ b/packages/web/src/content/docs/de/go.mdx @@ -62,6 +62,7 @@ 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** @@ -98,7 +99,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +118,7 @@ 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 @@ -140,6 +143,7 @@ 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 | @@ -197,6 +201,7 @@ 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` | @@ -218,28 +223,30 @@ 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.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 | +| 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 | - **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 a5ac30e060..1fa6cbc7eb 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/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` | +| 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` | | 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 c0908c7dcb..7182d716fc 100644 --- a/packages/web/src/content/docs/es/go.mdx +++ b/packages/web/src/content/docs/es/go.mdx @@ -70,6 +70,7 @@ 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** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +126,7 @@ 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 @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Utilizado | Sin acuerdo | +| DeepSeek V4 Flash | No utilizado | 0 días | | 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 e37a0592c9..539d5999f6 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/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` | +| 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` | | 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 2dc0b75d2f..c858645e44 100644 --- a/packages/web/src/content/docs/fr/go.mdx +++ b/packages/web/src/content/docs/fr/go.mdx @@ -60,6 +60,7 @@ 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** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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 @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | Utilisé | Aucun accord | +| DeepSeek V4 Flash | Non utilisé | 0 jour | | 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 24fa7341d9..7a5d5bcf7b 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/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` | +| 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` | | 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 29413ac112..507c901a76 100644 --- a/packages/web/src/content/docs/go.mdx +++ b/packages/web/src/content/docs/go.mdx @@ -70,6 +70,7 @@ 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** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +128,7 @@ 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 @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Used | No agreement | +| DeepSeek V4 Flash | Not used | 0 days | | 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 92726425c8..a724041640 100644 --- a/packages/web/src/content/docs/it/go.mdx +++ b/packages/web/src/content/docs/it/go.mdx @@ -68,6 +68,7 @@ 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** @@ -104,7 +105,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -122,6 +124,7 @@ 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 @@ -146,6 +149,7 @@ 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 | @@ -205,6 +209,7 @@ 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` | @@ -239,17 +244,19 @@ 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 | Utilizzato | Nessun accordo | +| DeepSeek V4 Flash | Non utilizzato | 0 giorni | | 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 3e3891b79d..941db5be94 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/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` | +| 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` | | 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 8439341656..963a36b1cc 100644 --- a/packages/web/src/content/docs/ja/go.mdx +++ b/packages/web/src/content/docs/ja/go.mdx @@ -60,6 +60,7 @@ OpenCode Goをサブスクライブできるのは、1つのワークスペー - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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トークン @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | 使用あり | 契約なし | +| DeepSeek V4 Flash | 使用なし | 0日 | | 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 f61f826f63..73b8d5a187 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/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` | +| 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` | | 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 30e06f9cc4..29693cdb6a 100644 --- a/packages/web/src/content/docs/ko/go.mdx +++ b/packages/web/src/content/docs/ko/go.mdx @@ -60,6 +60,7 @@ workspace당 한 명의 멤버만 OpenCode Go를 구독할 수 있습니다. - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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 @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | 사용됨 | 합의 없음 | +| DeepSeek V4 Flash | 사용되지 않음 | 0일 | | 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 b112aa742d..474bd38ff4 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/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` | +| 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` | | 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 bc13cc0946..afcc39e19b 100644 --- a/packages/web/src/content/docs/nb/go.mdx +++ b/packages/web/src/content/docs/nb/go.mdx @@ -70,6 +70,7 @@ 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** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +126,7 @@ 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 @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Ingen avtale | +| DeepSeek V4 Flash | Brukes ikke | 0 dager | | 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 379535eb7c..74cc45b3a9 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/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` | +| 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` | | 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 c15a2c11e5..f215736964 100644 --- a/packages/web/src/content/docs/pl/go.mdx +++ b/packages/web/src/content/docs/pl/go.mdx @@ -64,6 +64,7 @@ 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** @@ -100,7 +101,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +120,7 @@ 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 @@ -142,6 +145,7 @@ 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 | @@ -199,6 +203,7 @@ 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` | @@ -233,17 +238,19 @@ 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 | Wykorzystywane | Brak umowy | +| DeepSeek V4 Flash | Niewykorzystywane | 0 dni | | 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 a2df69cadf..c6c8ba7fb4 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/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` | +| 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` | | 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 20f4b08b84..fcfc8ed608 100644 --- a/packages/web/src/content/docs/pt-br/go.mdx +++ b/packages/web/src/content/docs/pt-br/go.mdx @@ -70,6 +70,7 @@ 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** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +126,7 @@ 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 @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Usado | Sem acordo | +| DeepSeek V4 Flash | Não usado | 0 dias | | 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 a657b88bd1..fa19e0e7d2 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/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` | +| 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` | | 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 dd3a272f0a..4df18953ef 100644 --- a/packages/web/src/content/docs/ru/go.mdx +++ b/packages/web/src/content/docs/ru/go.mdx @@ -70,6 +70,7 @@ OpenCode Go работает так же, как и любой другой пр - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -106,7 +107,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +126,7 @@ 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 выходных токенов на запрос @@ -148,6 +151,7 @@ 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 | @@ -207,6 +211,7 @@ 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` | @@ -241,17 +246,19 @@ 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 | Используется | Нет соглашения | +| DeepSeek V4 Flash | Не используется | 0 дней | | 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 4333abf0e5..f9633ac323 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/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` | +| 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` | | 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 38c0d9ebaa..f241b77ee0 100644 --- a/packages/web/src/content/docs/th/go.mdx +++ b/packages/web/src/content/docs/th/go.mdx @@ -60,6 +60,7 @@ OpenCode Go ทำงานเหมือนกับผู้ให้บร - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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 @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | นำไปใช้ | ไม่มีข้อตกลง | +| DeepSeek V4 Flash | ไม่นำไปใช้ | 0 วัน | | 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 99ba106a3c..2c256704ae 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/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` | +| 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` | | 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 a8861dde24..b480e0b2e5 100644 --- a/packages/web/src/content/docs/tr/go.mdx +++ b/packages/web/src/content/docs/tr/go.mdx @@ -60,6 +60,7 @@ 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** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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'ı @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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ılır | Anlaşma yok | +| DeepSeek V4 Flash | Kullanılmaz | 0 gün | | 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 ed5ea7d5fe..83f5cfea78 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/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` | +| 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` | | 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 6d57973c55..6be3aa7d99 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/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` | +| 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` | | 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 806bcd4b2b..ecf553f33d 100644 --- a/packages/web/src/content/docs/zh-cn/go.mdx +++ b/packages/web/src/content/docs/zh-cn/go.mdx @@ -60,6 +60,7 @@ OpenCode Go 的工作方式与 OpenCode 中的其他提供商一样。 - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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,6 +118,7 @@ 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 @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | 使用 | 无协议 | +| DeepSeek V4 Flash | 不使用 | 0 天 | | 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 4838ec4ed5..f4bb9cc502 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/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` | +| 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` | | 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 2959f63fa2..53da06c772 100644 --- a/packages/web/src/content/docs/zh-tw/go.mdx +++ b/packages/web/src/content/docs/zh-tw/go.mdx @@ -60,6 +60,7 @@ OpenCode Go 的運作方式與 OpenCode 中的任何其他供應商相同。 - **MiMo-V2.5-Pro** - **MiniMax M3** - **MiniMax M2.7** +- **Qwen3.8 Max** - **Qwen3.7 Max** - **Qwen3.7 Plus** - **Qwen3.6 Plus** @@ -96,7 +97,8 @@ 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.7 Max | 950 | 2,390 | 4,770 | +| Qwen3.8 Max | 160 | 400 | 810 | +| Qwen3.7 Max | 340 | 840 | 1,690 | | 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 | @@ -114,6 +116,7 @@ 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 @@ -138,6 +141,7 @@ 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 | @@ -195,6 +199,7 @@ 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` | @@ -227,17 +232,19 @@ 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 | 使用 | 無協議 | +| DeepSeek V4 Flash | 不使用 | 0 天 | | 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 54a8fcc92b..60b87c88df 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/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` | +| 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` | | 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 15943599b3..4c0e903459 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.10", + "version": "1.18.11", "publisher": "sst-dev", "repository": { "type": "git",