diff --git a/bun.lock b/bun.lock index 1c6bcd4716..7cb1578364 100644 --- a/bun.lock +++ b/bun.lock @@ -9,6 +9,7 @@ "@opencode-ai/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", "@opencode-ai/sdk": "workspace:*", + "heap-snapshot-toolkit": "1.1.3", "typescript": "catalog:", }, "devDependencies": { @@ -26,7 +27,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -80,7 +81,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -114,7 +115,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -141,7 +142,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@ai-sdk/anthropic": "3.0.64", "@ai-sdk/openai": "3.0.48", @@ -165,7 +166,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -189,7 +190,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -222,7 +223,7 @@ }, "packages/desktop-electron": { "name": "@opencode-ai/desktop-electron", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@opencode-ai/app": "workspace:*", "@opencode-ai/ui": "workspace:*", @@ -254,7 +255,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@opencode-ai/ui": "workspace:*", "@opencode-ai/util": "workspace:*", @@ -283,7 +284,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -299,7 +300,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.3.17", + "version": "1.4.0", "bin": { "opencode": "./bin/opencode", }, @@ -435,7 +436,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@opencode-ai/sdk": "workspace:*", "zod": "catalog:", @@ -469,7 +470,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "cross-spawn": "catalog:", }, @@ -484,7 +485,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -519,7 +520,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/sdk": "workspace:*", @@ -532,6 +533,7 @@ "@solid-primitives/resize-observer": "2.1.3", "@solidjs/meta": "catalog:", "@solidjs/router": "catalog:", + "diff": "catalog:", "dompurify": "3.3.1", "fuzzysort": "catalog:", "katex": "0.16.27", @@ -567,7 +569,7 @@ }, "packages/util": { "name": "@opencode-ai/util", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "zod": "catalog:", }, @@ -578,7 +580,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", @@ -3257,6 +3259,8 @@ "he": ["he@1.2.0", "", { "bin": { "he": "bin/he" } }, "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw=="], + "heap-snapshot-toolkit": ["heap-snapshot-toolkit@1.1.3", "", {}, "sha512-joThu2rEsDu8/l4arupRDI1qP4CZXNG+J6Wr348vnbLGSiBkwRdqZ6aOHl5BzEiC+Dc8OTbMlmWjD0lbXD5K2Q=="], + "hey-listen": ["hey-listen@1.0.8", "", {}, "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="], "hono": ["hono@4.10.7", "", {}, "sha512-icXIITfw/07Q88nLSkB9aiUrd8rYzSweK681Kjo/TSggaGbOX4RRyxxm71v+3PC8C/j+4rlxGeoTRxQDkaJkUw=="], diff --git a/nix/hashes.json b/nix/hashes.json index 0b8e34e786..f592339c2d 100644 --- a/nix/hashes.json +++ b/nix/hashes.json @@ -1,8 +1,8 @@ { "nodeModules": { - "x86_64-linux": "sha256-r1+AehuOGIOaaxfXkQGracT/6OdFRn5Ub8s7H+MeKFY=", - "aarch64-linux": "sha256-WkMSRF/ZJLyzxNBjpiMR459C9G0NVOEw31tm8roPneA=", - "aarch64-darwin": "sha256-Z127cxFpTl8Ml7PB3CG9TcCU08oYCPuk0FECK2MQ2CI=", - "x86_64-darwin": "sha256-pkRoFtnVjyl+5fm+rrFyRnEwvptxylnFxPAcEv4ZOCg=" + "x86_64-linux": "sha256-85wpU1oCWbthPleNIOj5d5AOuuYZ6rM7gMLZR6YJ2WU=", + "aarch64-linux": "sha256-C3A56SDQGJquCpIRj2JhIzr4A7N4cc9lxtEjl8bXDeM=", + "aarch64-darwin": "sha256-/Ij3qhGRrcLlMfl9uEacDNnGK5URxhctuQFBW4Njrog=", + "x86_64-darwin": "sha256-10sOPuN4eZ75orw4FI8ztCq1+AKS2e8aAfg3Z6Yn56w=" } } diff --git a/package.json b/package.json index 4ce36d17ec..d4713f95da 100644 --- a/package.json +++ b/package.json @@ -91,6 +91,7 @@ "@opencode-ai/plugin": "workspace:*", "@opencode-ai/script": "workspace:*", "@opencode-ai/sdk": "workspace:*", + "heap-snapshot-toolkit": "1.1.3", "typescript": "catalog:" }, "repository": { diff --git a/packages/app/e2e/actions.ts b/packages/app/e2e/actions.ts index b1c38afee5..ac9439360d 100644 --- a/packages/app/e2e/actions.ts +++ b/packages/app/e2e/actions.ts @@ -320,6 +320,7 @@ export async function createTestProject(input?: { serverUrl?: string }) { execSync("git init", { cwd: root, stdio: "ignore" }) await fs.writeFile(path.join(root, ".git", "opencode"), id) execSync("git config core.fsmonitor false", { cwd: root, stdio: "ignore" }) + execSync("git config commit.gpgsign false", { cwd: root, stdio: "ignore" }) execSync("git add -A", { cwd: root, stdio: "ignore" }) execSync('git -c user.name="e2e" -c user.email="e2e@example.com" commit -m "init" --allow-empty', { cwd: root, diff --git a/packages/app/package.json b/packages/app/package.json index cb52544eab..ea0f96e838 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.3.17", + "version": "1.4.0", "description": "", "type": "module", "exports": { diff --git a/packages/app/src/context/global-sync/event-reducer.ts b/packages/app/src/context/global-sync/event-reducer.ts index 4af6365535..01248e20e8 100644 --- a/packages/app/src/context/global-sync/event-reducer.ts +++ b/packages/app/src/context/global-sync/event-reducer.ts @@ -1,7 +1,6 @@ import { Binary } from "@opencode-ai/util/binary" import { produce, reconcile, type SetStoreFunction, type Store } from "solid-js/store" import type { - FileDiff, Message, Part, PermissionRequest, @@ -9,6 +8,7 @@ import type { QuestionRequest, Session, SessionStatus, + SnapshotFileDiff, Todo, } from "@opencode-ai/sdk/v2/client" import type { State, VcsCache } from "./types" @@ -161,7 +161,7 @@ export function applyDirectoryEvent(input: { break } case "session.diff": { - const props = event.properties as { sessionID: string; diff: FileDiff[] } + const props = event.properties as { sessionID: string; diff: SnapshotFileDiff[] } input.setStore("session_diff", props.sessionID, reconcile(props.diff, { key: "file" })) break } diff --git a/packages/app/src/context/global-sync/session-cache.test.ts b/packages/app/src/context/global-sync/session-cache.test.ts index 8e11110e3d..472ac219e9 100644 --- a/packages/app/src/context/global-sync/session-cache.test.ts +++ b/packages/app/src/context/global-sync/session-cache.test.ts @@ -1,11 +1,11 @@ import { describe, expect, test } from "bun:test" import type { - FileDiff, Message, Part, PermissionRequest, QuestionRequest, SessionStatus, + SnapshotFileDiff, Todo, } from "@opencode-ai/sdk/v2/client" import { dropSessionCaches, pickSessionCacheEvictions } from "./session-cache" @@ -33,7 +33,7 @@ describe("app session cache", () => { test("dropSessionCaches clears orphaned parts without message rows", () => { const store: { session_status: Record - session_diff: Record + session_diff: Record todo: Record message: Record part: Record @@ -64,7 +64,7 @@ describe("app session cache", () => { const m = msg("msg_1", "ses_1") const store: { session_status: Record - session_diff: Record + session_diff: Record todo: Record message: Record part: Record diff --git a/packages/app/src/context/global-sync/session-cache.ts b/packages/app/src/context/global-sync/session-cache.ts index 0177ebbe13..6f4d81062b 100644 --- a/packages/app/src/context/global-sync/session-cache.ts +++ b/packages/app/src/context/global-sync/session-cache.ts @@ -1,10 +1,10 @@ import type { - FileDiff, Message, Part, PermissionRequest, QuestionRequest, SessionStatus, + SnapshotFileDiff, Todo, } from "@opencode-ai/sdk/v2/client" @@ -12,7 +12,7 @@ export const SESSION_CACHE_LIMIT = 40 type SessionCache = { session_status: Record - session_diff: Record + session_diff: Record todo: Record message: Record part: Record diff --git a/packages/app/src/context/global-sync/types.ts b/packages/app/src/context/global-sync/types.ts index 1d6e550f8e..b0f340a902 100644 --- a/packages/app/src/context/global-sync/types.ts +++ b/packages/app/src/context/global-sync/types.ts @@ -2,7 +2,6 @@ import type { Agent, Command, Config, - FileDiff, LspStatus, McpStatus, Message, @@ -14,6 +13,7 @@ import type { QuestionRequest, Session, SessionStatus, + SnapshotFileDiff, Todo, VcsInfo, } from "@opencode-ai/sdk/v2/client" @@ -48,7 +48,7 @@ export type State = { [sessionID: string]: SessionStatus } session_diff: { - [sessionID: string]: FileDiff[] + [sessionID: string]: SnapshotFileDiff[] } todo: { [sessionID: string]: Todo[] diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 0c67647261..cf50fbe908 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1,4 +1,4 @@ -import type { FileDiff, Project, UserMessage } from "@opencode-ai/sdk/v2" +import type { Project, UserMessage, VcsFileDiff } from "@opencode-ai/sdk/v2" import { useDialog } from "@opencode-ai/ui/context/dialog" import { useMutation } from "@tanstack/solid-query" import { @@ -68,7 +68,7 @@ type FollowupItem = FollowupDraft & { id: string } type FollowupEdit = Pick const emptyFollowups: FollowupItem[] = [] -type ChangeMode = "git" | "branch" | "session" | "turn" +type ChangeMode = "git" | "branch" | "turn" type VcsMode = "git" | "branch" type SessionHistoryWindowInput = { @@ -463,13 +463,6 @@ export default function Page() { if (!id) return false return sync.session.history.loading(id) }) - const diffsReady = createMemo(() => { - const id = params.id - if (!id) return true - if (!hasSessionReview()) return true - return sync.data.session_diff[id] !== undefined - }) - const userMessages = createMemo( () => messages().filter((m) => m.role === "user") as UserMessage[], emptyUserMessages, @@ -527,10 +520,19 @@ export default function Page() { deferRender: false, }) - const [vcs, setVcs] = createStore({ + const [vcs, setVcs] = createStore<{ diff: { - git: [] as FileDiff[], - branch: [] as FileDiff[], + git: VcsFileDiff[] + branch: VcsFileDiff[] + } + ready: { + git: boolean + branch: boolean + } + }>({ + diff: { + git: [] as VcsFileDiff[], + branch: [] as VcsFileDiff[], }, ready: { git: false, @@ -648,6 +650,7 @@ export default function Page() { }, desktopReviewOpen()) const turnDiffs = createMemo(() => lastUserMessage()?.summary?.diffs ?? []) + const nogit = createMemo(() => !!sync.project && sync.project.vcs !== "git") const changesOptions = createMemo(() => { const list: ChangeMode[] = [] if (sync.project?.vcs === "git") list.push("git") @@ -659,7 +662,7 @@ export default function Page() { ) { list.push("branch") } - list.push("session", "turn") + list.push("turn") return list }) const vcsMode = createMemo(() => { @@ -668,20 +671,17 @@ export default function Page() { const reviewDiffs = createMemo(() => { if (store.changes === "git") return vcs.diff.git if (store.changes === "branch") return vcs.diff.branch - if (store.changes === "session") return diffs() return turnDiffs() }) const reviewCount = createMemo(() => { if (store.changes === "git") return vcs.diff.git.length if (store.changes === "branch") return vcs.diff.branch.length - if (store.changes === "session") return sessionCount() return turnDiffs().length }) const hasReview = createMemo(() => reviewCount() > 0) const reviewReady = createMemo(() => { if (store.changes === "git") return vcs.ready.git if (store.changes === "branch") return vcs.ready.branch - if (store.changes === "session") return !hasSessionReview() || diffsReady() return true }) @@ -749,13 +749,6 @@ export default function Page() { scrollToMessage(msgs[targetIndex], "auto") } - const sessionEmptyKey = createMemo(() => { - const project = sync.project - if (project && !project.vcs) return "session.review.noVcs" - if (sync.data.config.snapshot === false) return "session.review.noSnapshot" - return "session.review.empty" - }) - function upsert(next: Project) { const list = globalSync.data.project sync.set("project", next.id) @@ -1156,7 +1149,6 @@ export default function Page() { const label = (option: ChangeMode) => { if (option === "git") return language.t("ui.sessionReview.title.git") if (option === "branch") return language.t("ui.sessionReview.title.branch") - if (option === "session") return language.t("ui.sessionReview.title") return language.t("ui.sessionReview.title.lastTurn") } @@ -1179,11 +1171,26 @@ export default function Page() { ) + const createGit = (input: { emptyClass: string }) => ( +
+
+
{language.t("session.review.noVcs.createGit.title")}
+
+ {language.t("session.review.noVcs.createGit.description")} +
+
+ +
+ ) + const reviewEmptyText = createMemo(() => { if (store.changes === "git") return language.t("session.review.noUncommittedChanges") if (store.changes === "branch") return language.t("session.review.noBranchChanges") - if (store.changes === "turn") return language.t("session.review.noChanges") - return language.t(sessionEmptyKey()) + return language.t("session.review.noChanges") }) const reviewEmpty = (input: { loadingClass: string; emptyClass: string }) => { @@ -1193,31 +1200,10 @@ export default function Page() { } if (store.changes === "turn") { + if (nogit()) return createGit(input) return empty(reviewEmptyText()) } - if (hasSessionReview() && !diffsReady()) { - return
{language.t("session.review.loadingChanges")}
- } - - if (sessionEmptyKey() === "session.review.noVcs") { - return ( -
-
-
{language.t("session.review.noVcs.createGit.title")}
-
- {language.t("session.review.noVcs.createGit.description")} -
-
- -
- ) - } - return (
{reviewEmptyText()}
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx index b681286450..71dfe375e0 100644 --- a/packages/app/src/pages/session/review-tab.tsx +++ b/packages/app/src/pages/session/review-tab.tsx @@ -1,6 +1,6 @@ import { createEffect, createSignal, onCleanup, type JSX } from "solid-js" import { makeEventListener } from "@solid-primitives/event-listener" -import type { FileDiff } from "@opencode-ai/sdk/v2" +import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2" import { SessionReview } from "@opencode-ai/ui/session-review" import type { SessionReviewCommentActions, @@ -14,10 +14,12 @@ import type { LineComment } from "@/context/comments" export type DiffStyle = "unified" | "split" +type ReviewDiff = SnapshotFileDiff | VcsFileDiff + export interface SessionReviewTabProps { title?: JSX.Element empty?: JSX.Element - diffs: () => FileDiff[] + diffs: () => ReviewDiff[] view: () => ReturnType["view"]> diffStyle: DiffStyle onDiffStyleChange?: (style: DiffStyle) => void diff --git a/packages/app/src/pages/session/session-side-panel.tsx b/packages/app/src/pages/session/session-side-panel.tsx index 86f932ea25..cddbea84d6 100644 --- a/packages/app/src/pages/session/session-side-panel.tsx +++ b/packages/app/src/pages/session/session-side-panel.tsx @@ -8,7 +8,7 @@ import { ResizeHandle } from "@opencode-ai/ui/resize-handle" import { Mark } from "@opencode-ai/ui/logo" import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd" import type { DragEvent } from "@thisbeyond/solid-dnd" -import type { FileDiff } from "@opencode-ai/sdk/v2" +import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2" import { ConstrainDragYAxis, getDraggableId } from "@/utils/solid-dnd" import { useDialog } from "@opencode-ai/ui/context/dialog" @@ -27,7 +27,7 @@ import { useSessionLayout } from "@/pages/session/session-layout" export function SessionSidePanel(props: { canReview: () => boolean - diffs: () => FileDiff[] + diffs: () => (SnapshotFileDiff | VcsFileDiff)[] diffsReady: () => boolean empty: () => string hasReview: () => boolean diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 1a01bf21b2..e13d72b60f 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/app/src/i18n/ar.ts b/packages/console/app/src/i18n/ar.ts index 49230601e3..387a8503b1 100644 --- a/packages/console/app/src/i18n/ar.ts +++ b/packages/console/app/src/i18n/ar.ts @@ -249,7 +249,7 @@ export const dict = { "go.title": "OpenCode Go | نماذج برمجة منخفضة التكلفة للجميع", "go.meta.description": - "يبدأ Go من $5 للشهر الأول، ثم $10/شهر، مع حدود طلب سخية لمدة 5 ساعات لـ GLM-5 و Kimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni و MiniMax M2.5 وMiniMax M2.7.", + "يبدأ Go من $5 للشهر الأول، ثم $10/شهر، مع حدود طلب سخية لمدة 5 ساعات لـ GLM-5.1 وGLM-5 و Kimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni و MiniMax M2.5 وMiniMax M2.7.", "go.hero.title": "نماذج برمجة منخفضة التكلفة للجميع", "go.hero.body": "يجلب Go البرمجة الوكيلة للمبرمجين حول العالم. يوفر حدودًا سخية ووصولًا موثوقًا إلى أقوى النماذج مفتوحة المصدر، حتى تتمكن من البناء باستخدام وكلاء أقوياء دون القلق بشأن التكلفة أو التوفر.", @@ -297,7 +297,7 @@ export const dict = { "go.problem.item1": "أسعار اشتراك منخفضة التكلفة", "go.problem.item2": "حدود سخية ووصول موثوق", "go.problem.item3": "مصمم لأكبر عدد ممكن من المبرمجين", - "go.problem.item4": "يتضمن GLM-5 وKimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni وMiniMax M2.5 وMiniMax M2.7", + "go.problem.item4": "يتضمن GLM-5.1 وGLM-5 وKimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni وMiniMax M2.5 وMiniMax M2.7", "go.how.title": "كيف يعمل Go", "go.how.body": "يبدأ Go من $5 للشهر الأول، ثم $10/شهر. يمكنك استخدامه مع OpenCode أو أي وكيل.", "go.how.step1.title": "أنشئ حسابًا", @@ -319,10 +319,10 @@ export const dict = { "go.faq.a1": "Go هو اشتراك منخفض التكلفة يمنحك وصولًا موثوقًا إلى نماذج مفتوحة المصدر قادرة على البرمجة الوكيلة.", "go.faq.q2": "ما النماذج التي يتضمنها Go؟", "go.faq.a2": - "يتضمن Go نماذج GLM-5 وKimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni وMiniMax M2.5 وMiniMax M2.7، مع حدود سخية ووصول موثوق.", + "يتضمن Go نماذج GLM-5.1 وGLM-5 وKimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni وMiniMax M2.5 وMiniMax M2.7، مع حدود سخية ووصول موثوق.", "go.faq.q3": "هل Go هو نفسه Zen؟", "go.faq.a3": - "لا. Zen هو الدفع حسب الاستخدام، بينما يبدأ Go من $5 للشهر الأول، ثم $10/شهر، مع حدود سخية ووصول موثوق إلى نماذج المصدر المفتوح GLM-5 و Kimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni و MiniMax M2.5 وMiniMax M2.7.", + "لا. Zen هو الدفع حسب الاستخدام، بينما يبدأ Go من $5 للشهر الأول، ثم $10/شهر، مع حدود سخية ووصول موثوق إلى نماذج المصدر المفتوح GLM-5.1 وGLM-5 و Kimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni و MiniMax M2.5 وMiniMax M2.7.", "go.faq.q4": "كم تكلفة Go؟", "go.faq.a4.p1.beforePricing": "تكلفة Go", "go.faq.a4.p1.pricingLink": "$5 للشهر الأول", @@ -345,7 +345,7 @@ export const dict = { "go.faq.q9": "ما الفرق بين النماذج المجانية وGo؟", "go.faq.a9": - "تشمل النماذج المجانية Big Pickle بالإضافة إلى النماذج الترويجية المتاحة في ذلك الوقت، مع حصة 200 طلب/يوم. يتضمن Go نماذج GLM-5 وKimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni وMiniMax M2.5 وMiniMax M2.7 مع حصص طلبات أعلى مطبقة عبر نوافذ متجددة (5 ساعات، أسبوعيًا، وشهريًا)، تعادل تقريبًا 12 دولارًا كل 5 ساعات، و30 دولارًا في الأسبوع، و60 دولارًا في الشهر (تختلف أعداد الطلبات الفعلية حسب النموذج والاستخدام).", + "تشمل النماذج المجانية Big Pickle بالإضافة إلى النماذج الترويجية المتاحة في ذلك الوقت، مع حصة 200 طلب/يوم. يتضمن Go نماذج GLM-5.1 وGLM-5 وKimi K2.5 وMiMo-V2-Pro وMiMo-V2-Omni وMiniMax M2.5 وMiniMax M2.7 مع حصص طلبات أعلى مطبقة عبر نوافذ متجددة (5 ساعات، أسبوعيًا، وشهريًا)، تعادل تقريبًا 12 دولارًا كل 5 ساعات، و30 دولارًا في الأسبوع، و60 دولارًا في الشهر (تختلف أعداد الطلبات الفعلية حسب النموذج والاستخدام).", "zen.api.error.rateLimitExceeded": "تم تجاوز حد الطلبات. يرجى المحاولة مرة أخرى لاحقًا.", "zen.api.error.modelNotSupported": "النموذج {{model}} غير مدعوم", diff --git a/packages/console/app/src/i18n/br.ts b/packages/console/app/src/i18n/br.ts index adc2909f9e..33efd85d18 100644 --- a/packages/console/app/src/i18n/br.ts +++ b/packages/console/app/src/i18n/br.ts @@ -253,7 +253,7 @@ export const dict = { "go.title": "OpenCode Go | Modelos de codificação de baixo custo para todos", "go.meta.description": - "O Go começa em $5 no primeiro mês, depois $10/mês, com limites generosos de solicitação de 5 horas para GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", + "O Go começa em $5 no primeiro mês, depois $10/mês, com limites generosos de solicitação de 5 horas para GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", "go.hero.title": "Modelos de codificação de baixo custo para todos", "go.hero.body": "O Go traz a codificação com agentes para programadores em todo o mundo. Oferecendo limites generosos e acesso confiável aos modelos de código aberto mais capazes, para que você possa construir com agentes poderosos sem se preocupar com custos ou disponibilidade.", @@ -302,7 +302,7 @@ export const dict = { "go.problem.item1": "Preço de assinatura de baixo custo", "go.problem.item2": "Limites generosos e acesso confiável", "go.problem.item3": "Feito para o maior número possível de programadores", - "go.problem.item4": "Inclui GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7", + "go.problem.item4": "Inclui GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7", "go.how.title": "Como o Go funciona", "go.how.body": "O Go começa em $5 no primeiro mês, depois $10/mês. Você pode usá-lo com o OpenCode ou qualquer agente.", @@ -326,10 +326,10 @@ export const dict = { "Go é uma assinatura de baixo custo que oferece acesso confiável a modelos de código aberto capazes para codificação com agentes.", "go.faq.q2": "Quais modelos o Go inclui?", "go.faq.a2": - "Go inclui GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7, com limites generosos e acesso confiável.", + "Go inclui GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7, com limites generosos e acesso confiável.", "go.faq.q3": "O Go é o mesmo que o Zen?", "go.faq.a3": - "Não. Zen é pay-as-you-go, enquanto o Go começa em $5 no primeiro mês, depois $10/mês, com limites generosos e acesso confiável aos modelos open source GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", + "Não. Zen é pay-as-you-go, enquanto o Go começa em $5 no primeiro mês, depois $10/mês, com limites generosos e acesso confiável aos modelos open source GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", "go.faq.q4": "Quanto custa o Go?", "go.faq.a4.p1.beforePricing": "O Go custa", "go.faq.a4.p1.pricingLink": "$5 no primeiro mês", @@ -353,7 +353,7 @@ export const dict = { "go.faq.q9": "Qual a diferença entre os modelos gratuitos e o Go?", "go.faq.a9": - "Os modelos gratuitos incluem Big Pickle e modelos promocionais disponíveis no momento, com uma cota de 200 requisições/dia. O Go inclui GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7 com cotas de requisição mais altas aplicadas em janelas móveis (5 horas, semanal e mensal), aproximadamente equivalentes a $12 por 5 horas, $30 por semana e $60 por mês (as contagens reais de requisições variam de acordo com o modelo e o uso).", + "Os modelos gratuitos incluem Big Pickle e modelos promocionais disponíveis no momento, com uma cota de 200 requisições/dia. O Go inclui GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7 com cotas de requisição mais altas aplicadas em janelas móveis (5 horas, semanal e mensal), aproximadamente equivalentes a $12 por 5 horas, $30 por semana e $60 por mês (as contagens reais de requisições variam de acordo com o modelo e o uso).", "zen.api.error.rateLimitExceeded": "Limite de taxa excedido. Por favor, tente novamente mais tarde.", "zen.api.error.modelNotSupported": "Modelo {{model}} não suportado", diff --git a/packages/console/app/src/i18n/da.ts b/packages/console/app/src/i18n/da.ts index e657a04aba..abcdef2705 100644 --- a/packages/console/app/src/i18n/da.ts +++ b/packages/console/app/src/i18n/da.ts @@ -251,7 +251,7 @@ export const dict = { "go.title": "OpenCode Go | Kodningsmodeller til lav pris for alle", "go.meta.description": - "Go starter ved $5 for den første måned, derefter $10/måned, med generøse 5-timers anmodningsgrænser for GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", + "Go starter ved $5 for den første måned, derefter $10/måned, med generøse 5-timers anmodningsgrænser for GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", "go.hero.title": "Kodningsmodeller til lav pris for alle", "go.hero.body": "Go bringer agentisk kodning til programmører over hele verden. Med generøse grænser og pålidelig adgang til de mest kapable open source-modeller, så du kan bygge med kraftfulde agenter uden at bekymre dig om omkostninger eller tilgængelighed.", @@ -299,7 +299,7 @@ export const dict = { "go.problem.item1": "Lavpris abonnementspriser", "go.problem.item2": "Generøse grænser og pålidelig adgang", "go.problem.item3": "Bygget til så mange programmører som muligt", - "go.problem.item4": "Inkluderer GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7", + "go.problem.item4": "Inkluderer GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7", "go.how.title": "Hvordan Go virker", "go.how.body": "Go starter ved $5 for den første måned, derefter $10/måned. Du kan bruge det med OpenCode eller enhver agent.", @@ -323,10 +323,10 @@ export const dict = { "Go er et lavprisabonnement, der giver dig pålidelig adgang til kapable open source-modeller til agentisk kodning.", "go.faq.q2": "Hvilke modeller inkluderer Go?", "go.faq.a2": - "Go inkluderer GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7, med generøse grænser og pålidelig adgang.", + "Go inkluderer GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7, med generøse grænser og pålidelig adgang.", "go.faq.q3": "Er Go det samme som Zen?", "go.faq.a3": - "Nej. Zen er pay-as-you-go, mens Go starter ved $5 for den første måned, derefter $10/måned, med generøse grænser og pålidelig adgang til open source-modellerne GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", + "Nej. Zen er pay-as-you-go, mens Go starter ved $5 for den første måned, derefter $10/måned, med generøse grænser og pålidelig adgang til open source-modellerne GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", "go.faq.q4": "Hvad koster Go?", "go.faq.a4.p1.beforePricing": "Go koster", "go.faq.a4.p1.pricingLink": "$5 første måned", @@ -349,7 +349,7 @@ export const dict = { "go.faq.q9": "Hvad er forskellen på gratis modeller og Go?", "go.faq.a9": - "Gratis modeller inkluderer Big Pickle plus salgsfremmende modeller tilgængelige på det tidspunkt, med en kvote på 200 forespørgsler/dag. Go inkluderer GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7 med højere anmodningskvoter håndhævet over rullende vinduer (5-timers, ugentlig og månedlig), nogenlunde svarende til $12 pr. 5 timer, $30 pr. uge og $60 pr. måned (faktiske anmodningstal varierer efter model og brug).", + "Gratis modeller inkluderer Big Pickle plus salgsfremmende modeller tilgængelige på det tidspunkt, med en kvote på 200 forespørgsler/dag. Go inkluderer GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7 med højere anmodningskvoter håndhævet over rullende vinduer (5-timers, ugentlig og månedlig), nogenlunde svarende til $12 pr. 5 timer, $30 pr. uge og $60 pr. måned (faktiske anmodningstal varierer efter model og brug).", "zen.api.error.rateLimitExceeded": "Hastighedsgrænse overskredet. Prøv venligst igen senere.", "zen.api.error.modelNotSupported": "Model {{model}} understøttes ikke", diff --git a/packages/console/app/src/i18n/de.ts b/packages/console/app/src/i18n/de.ts index b68663bb2d..cacd450fa0 100644 --- a/packages/console/app/src/i18n/de.ts +++ b/packages/console/app/src/i18n/de.ts @@ -253,7 +253,7 @@ export const dict = { "go.title": "OpenCode Go | Kostengünstige Coding-Modelle für alle", "go.meta.description": - "Go beginnt bei $5 für den ersten Monat, danach $10/Monat, mit großzügigen 5-Stunden-Anfragelimits für GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7.", + "Go beginnt bei $5 für den ersten Monat, danach $10/Monat, mit großzügigen 5-Stunden-Anfragelimits für GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7.", "go.hero.title": "Kostengünstige Coding-Modelle für alle", "go.hero.body": "Go bringt Agentic Coding zu Programmierern auf der ganzen Welt. Mit großzügigen Limits und zuverlässigem Zugang zu den leistungsfähigsten Open-Source-Modellen, damit du mit leistungsstarken Agenten entwickeln kannst, ohne dir Gedanken über Kosten oder Verfügbarkeit zu machen.", @@ -301,7 +301,7 @@ export const dict = { "go.problem.item1": "Kostengünstiges Abonnement", "go.problem.item2": "Großzügige Limits und zuverlässiger Zugang", "go.problem.item3": "Für so viele Programmierer wie möglich gebaut", - "go.problem.item4": "Beinhaltet GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7", + "go.problem.item4": "Beinhaltet GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7", "go.how.title": "Wie Go funktioniert", "go.how.body": "Go beginnt bei $5 für den ersten Monat, danach $10/Monat. Du kannst es mit OpenCode oder jedem Agenten nutzen.", @@ -325,10 +325,10 @@ export const dict = { "Go ist ein kostengünstiges Abonnement, das dir zuverlässigen Zugang zu leistungsfähigen Open-Source-Modellen für Agentic Coding bietet.", "go.faq.q2": "Welche Modelle beinhaltet Go?", "go.faq.a2": - "Go beinhaltet GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7, mit großzügigen Limits und zuverlässigem Zugang.", + "Go beinhaltet GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7, mit großzügigen Limits und zuverlässigem Zugang.", "go.faq.q3": "Ist Go dasselbe wie Zen?", "go.faq.a3": - "Nein. Zen ist Pay-as-you-go, während Go bei $5 für den ersten Monat beginnt, danach $10/Monat, mit großzügigen Limits und zuverlässigem Zugang zu den Open-Source-Modellen GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7.", + "Nein. Zen ist Pay-as-you-go, während Go bei $5 für den ersten Monat beginnt, danach $10/Monat, mit großzügigen Limits und zuverlässigem Zugang zu den Open-Source-Modellen GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7.", "go.faq.q4": "Wie viel kostet Go?", "go.faq.a4.p1.beforePricing": "Go kostet", "go.faq.a4.p1.pricingLink": "$5 im ersten Monat", @@ -352,7 +352,7 @@ export const dict = { "go.faq.q9": "Was ist der Unterschied zwischen kostenlosen Modellen und Go?", "go.faq.a9": - "Kostenlose Modelle beinhalten Big Pickle sowie Werbemodelle, die zum jeweiligen Zeitpunkt verfügbar sind, mit einem Kontingent von 200 Anfragen/Tag. Go beinhaltet GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7 mit höheren Anfragekontingenten, die über rollierende Zeitfenster (5 Stunden, wöchentlich und monatlich) durchgesetzt werden, grob äquivalent zu $12 pro 5 Stunden, $30 pro Woche und $60 pro Monat (tatsächliche Anfragezahlen variieren je nach Modell und Nutzung).", + "Kostenlose Modelle beinhalten Big Pickle sowie Werbemodelle, die zum jeweiligen Zeitpunkt verfügbar sind, mit einem Kontingent von 200 Anfragen/Tag. Go beinhaltet GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 und MiniMax M2.7 mit höheren Anfragekontingenten, die über rollierende Zeitfenster (5 Stunden, wöchentlich und monatlich) durchgesetzt werden, grob äquivalent zu $12 pro 5 Stunden, $30 pro Woche und $60 pro Monat (tatsächliche Anfragezahlen variieren je nach Modell und Nutzung).", "zen.api.error.rateLimitExceeded": "Ratenlimit überschritten. Bitte versuche es später erneut.", "zen.api.error.modelNotSupported": "Modell {{model}} wird nicht unterstützt", diff --git a/packages/console/app/src/i18n/en.ts b/packages/console/app/src/i18n/en.ts index c50fada2a2..2de627b478 100644 --- a/packages/console/app/src/i18n/en.ts +++ b/packages/console/app/src/i18n/en.ts @@ -248,7 +248,7 @@ export const dict = { "go.title": "OpenCode Go | Low cost coding models for everyone", "go.meta.description": - "Go starts at $5 for your first month, then $10/month, with generous 5-hour request limits for GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7.", + "Go starts at $5 for your first month, then $10/month, with generous 5-hour request limits for GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7.", "go.hero.title": "Low cost coding models for everyone", "go.hero.body": "Go brings agentic coding to programmers around the world. Offering generous limits and reliable access to the most capable open-source models, so you can build with powerful agents without worrying about cost or availability.", @@ -295,7 +295,7 @@ export const dict = { "go.problem.item1": "Low cost subscription pricing", "go.problem.item2": "Generous limits and reliable access", "go.problem.item3": "Built for as many programmers as possible", - "go.problem.item4": "Includes GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7", + "go.problem.item4": "Includes GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7", "go.how.title": "How Go works", "go.how.body": "Go starts at $5 for your first month, then $10/month. You can use it with OpenCode or any agent.", "go.how.step1.title": "Create an account", @@ -318,10 +318,10 @@ export const dict = { "Go is a low-cost subscription that gives you reliable access to capable open-source models for agentic coding.", "go.faq.q2": "What models does Go include?", "go.faq.a2": - "Go includes GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7, with generous limits and reliable access.", + "Go includes GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7, with generous limits and reliable access.", "go.faq.q3": "Is Go the same as Zen?", "go.faq.a3": - "No. Zen is pay-as-you-go, while Go starts at $5 for your first month, then $10/month, with generous limits and reliable access to open-source models GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7.", + "No. Zen is pay-as-you-go, while Go starts at $5 for your first month, then $10/month, with generous limits and reliable access to open-source models GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7.", "go.faq.q4": "How much does Go cost?", "go.faq.a4.p1.beforePricing": "Go costs", "go.faq.a4.p1.pricingLink": "$5 first month", @@ -345,7 +345,7 @@ export const dict = { "go.faq.q9": "What is the difference between free models and Go?", "go.faq.a9": - "Free models include Big Pickle plus promotional models available at the time, with a quota of 200 requests/day. Go includes GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7 with higher request quotas enforced across rolling windows (5-hour, weekly, and monthly), roughly equivalent to $12 per 5 hours, $30 per week, and $60 per month (actual request counts vary by model and usage).", + "Free models include Big Pickle plus promotional models available at the time, with a quota of 200 requests/day. Go includes GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, and MiniMax M2.7 with higher request quotas enforced across rolling windows (5-hour, weekly, and monthly), roughly equivalent to $12 per 5 hours, $30 per week, and $60 per month (actual request counts vary by model and usage).", "zen.api.error.rateLimitExceeded": "Rate limit exceeded. Please try again later.", "zen.api.error.modelNotSupported": "Model {{model}} not supported", diff --git a/packages/console/app/src/i18n/es.ts b/packages/console/app/src/i18n/es.ts index a8ff071a89..065f67a722 100644 --- a/packages/console/app/src/i18n/es.ts +++ b/packages/console/app/src/i18n/es.ts @@ -254,7 +254,7 @@ export const dict = { "go.title": "OpenCode Go | Modelos de programación de bajo coste para todos", "go.meta.description": - "Go comienza en $5 el primer mes, luego 10 $/mes, con generosos límites de solicitudes de 5 horas para GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7.", + "Go comienza en $5 el primer mes, luego 10 $/mes, con generosos límites de solicitudes de 5 horas para GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7.", "go.hero.title": "Modelos de programación de bajo coste para todos", "go.hero.body": "Go lleva la programación agéntica a programadores de todo el mundo. Ofrece límites generosos y acceso fiable a los modelos de código abierto más capaces, para que puedas crear con agentes potentes sin preocuparte por el coste o la disponibilidad.", @@ -303,7 +303,7 @@ export const dict = { "go.problem.item1": "Precios de suscripción de bajo coste", "go.problem.item2": "Límites generosos y acceso fiable", "go.problem.item3": "Creado para tantos programadores como sea posible", - "go.problem.item4": "Incluye GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7", + "go.problem.item4": "Incluye GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7", "go.how.title": "Cómo funciona Go", "go.how.body": "Go comienza en $5 el primer mes, luego 10 $/mes. Puedes usarlo con OpenCode o cualquier agente.", "go.how.step1.title": "Crear una cuenta", @@ -326,10 +326,10 @@ export const dict = { "Go es una suscripción de bajo coste que te da acceso fiable a modelos de código abierto capaces para programación agéntica.", "go.faq.q2": "¿Qué modelos incluye Go?", "go.faq.a2": - "Go incluye GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7, con límites generosos y acceso fiable.", + "Go incluye GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7, con límites generosos y acceso fiable.", "go.faq.q3": "¿Es Go lo mismo que Zen?", "go.faq.a3": - "No. Zen es pago por uso, mientras que Go comienza en $5 el primer mes, luego 10 $/mes, con límites generosos y acceso fiable a los modelos de código abierto GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7.", + "No. Zen es pago por uso, mientras que Go comienza en $5 el primer mes, luego 10 $/mes, con límites generosos y acceso fiable a los modelos de código abierto GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7.", "go.faq.q4": "¿Cuánto cuesta Go?", "go.faq.a4.p1.beforePricing": "Go cuesta", "go.faq.a4.p1.pricingLink": "$5 el primer mes", @@ -353,7 +353,7 @@ export const dict = { "go.faq.q9": "¿Cuál es la diferencia entre los modelos gratuitos y Go?", "go.faq.a9": - "Los modelos gratuitos incluyen Big Pickle más modelos promocionales disponibles en el momento, con una cuota de 200 solicitudes/día. Go incluye GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7 con cuotas de solicitud más altas aplicadas a través de ventanas móviles (5 horas, semanal y mensual), aproximadamente equivalente a 12 $ por 5 horas, 30 $ por semana y 60 $ por mes (los recuentos reales de solicitudes varían según el modelo y el uso).", + "Los modelos gratuitos incluyen Big Pickle más modelos promocionales disponibles en el momento, con una cuota de 200 solicitudes/día. Go incluye GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 y MiniMax M2.7 con cuotas de solicitud más altas aplicadas a través de ventanas móviles (5 horas, semanal y mensual), aproximadamente equivalente a 12 $ por 5 horas, 30 $ por semana y 60 $ por mes (los recuentos reales de solicitudes varían según el modelo y el uso).", "zen.api.error.rateLimitExceeded": "Límite de tasa excedido. Por favor, inténtalo de nuevo más tarde.", "zen.api.error.modelNotSupported": "Modelo {{model}} no soportado", diff --git a/packages/console/app/src/i18n/fr.ts b/packages/console/app/src/i18n/fr.ts index 1812d2c5d3..7d280f8b7e 100644 --- a/packages/console/app/src/i18n/fr.ts +++ b/packages/console/app/src/i18n/fr.ts @@ -255,7 +255,7 @@ export const dict = { "go.title": "OpenCode Go | Modèles de code à faible coût pour tous", "go.meta.description": - "Go commence à $5 pour le premier mois, puis 10 $/mois, avec des limites de requêtes généreuses sur 5 heures pour GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7.", + "Go commence à $5 pour le premier mois, puis 10 $/mois, avec des limites de requêtes généreuses sur 5 heures pour GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7.", "go.hero.title": "Modèles de code à faible coût pour tous", "go.hero.body": "Go apporte le codage agentique aux programmeurs du monde entier. Offrant des limites généreuses et un accès fiable aux modèles open source les plus capables, pour que vous puissiez construire avec des agents puissants sans vous soucier du coût ou de la disponibilité.", @@ -303,7 +303,7 @@ export const dict = { "go.problem.item1": "Prix d'abonnement bas", "go.problem.item2": "Limites généreuses et accès fiable", "go.problem.item3": "Conçu pour autant de programmeurs que possible", - "go.problem.item4": "Inclut GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7", + "go.problem.item4": "Inclut GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7", "go.how.title": "Comment fonctionne Go", "go.how.body": "Go commence à $5 pour le premier mois, puis 10 $/mois. Vous pouvez l'utiliser avec OpenCode ou n'importe quel agent.", @@ -327,10 +327,10 @@ export const dict = { "Go est un abonnement à faible coût qui vous donne un accès fiable à des modèles open source performants pour le codage agentique.", "go.faq.q2": "Quels modèles Go inclut-il ?", "go.faq.a2": - "Go inclut GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7, avec des limites généreuses et un accès fiable.", + "Go inclut GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7, avec des limites généreuses et un accès fiable.", "go.faq.q3": "Est-ce que Go est la même chose que Zen ?", "go.faq.a3": - "Non. Zen est un paiement à l'utilisation, tandis que Go commence à $5 pour le premier mois, puis 10 $/mois, avec des limites généreuses et un accès fiable aux modèles open source GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7.", + "Non. Zen est un paiement à l'utilisation, tandis que Go commence à $5 pour le premier mois, puis 10 $/mois, avec des limites généreuses et un accès fiable aux modèles open source GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7.", "go.faq.q4": "Combien coûte Go ?", "go.faq.a4.p1.beforePricing": "Go coûte", "go.faq.a4.p1.pricingLink": "$5 le premier mois", @@ -353,7 +353,7 @@ export const dict = { "Oui, vous pouvez utiliser Go avec n'importe quel agent. Suivez les instructions de configuration dans votre agent de code préféré.", "go.faq.q9": "Quelle est la différence entre les modèles gratuits et Go ?", "go.faq.a9": - "Les modèles gratuits incluent Big Pickle ainsi que des modèles promotionnels disponibles à ce moment-là, avec un quota de 200 requêtes/jour. Go inclut GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7 avec des quotas de requêtes plus élevés appliqués sur des fenêtres glissantes (5 heures, hebdomadaire et mensuelle), à peu près équivalent à 12 $ par 5 heures, 30 $ par semaine et 60 $ par mois (le nombre réel de requêtes varie selon le modèle et l'utilisation).", + "Les modèles gratuits incluent Big Pickle ainsi que des modèles promotionnels disponibles à ce moment-là, avec un quota de 200 requêtes/jour. Go inclut GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 et MiniMax M2.7 avec des quotas de requêtes plus élevés appliqués sur des fenêtres glissantes (5 heures, hebdomadaire et mensuelle), à peu près équivalent à 12 $ par 5 heures, 30 $ par semaine et 60 $ par mois (le nombre réel de requêtes varie selon le modèle et l'utilisation).", "zen.api.error.rateLimitExceeded": "Limite de débit dépassée. Veuillez réessayer plus tard.", "zen.api.error.modelNotSupported": "Modèle {{model}} non pris en charge", diff --git a/packages/console/app/src/i18n/it.ts b/packages/console/app/src/i18n/it.ts index d56556a093..80daeeb5d9 100644 --- a/packages/console/app/src/i18n/it.ts +++ b/packages/console/app/src/i18n/it.ts @@ -251,7 +251,7 @@ export const dict = { "go.title": "OpenCode Go | Modelli di coding a basso costo per tutti", "go.meta.description": - "Go inizia a $5 per il primo mese, poi $10/mese, con generosi limiti di richiesta di 5 ore per GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", + "Go inizia a $5 per il primo mese, poi $10/mese, con generosi limiti di richiesta di 5 ore per GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", "go.hero.title": "Modelli di coding a basso costo per tutti", "go.hero.body": "Go porta il coding agentico ai programmatori di tutto il mondo. Offrendo limiti generosi e un accesso affidabile ai modelli open source più capaci, in modo da poter costruire con agenti potenti senza preoccuparsi dei costi o della disponibilità.", @@ -299,7 +299,7 @@ export const dict = { "go.problem.item1": "Prezzo di abbonamento a basso costo", "go.problem.item2": "Limiti generosi e accesso affidabile", "go.problem.item3": "Costruito per il maggior numero possibile di programmatori", - "go.problem.item4": "Include GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7", + "go.problem.item4": "Include GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7", "go.how.title": "Come funziona Go", "go.how.body": "Go inizia a $5 per il primo mese, poi $10/mese. Puoi usarlo con OpenCode o qualsiasi agente.", "go.how.step1.title": "Crea un account", @@ -322,10 +322,10 @@ export const dict = { "Go è un abbonamento a basso costo che ti dà un accesso affidabile a modelli open source capaci per il coding agentico.", "go.faq.q2": "Quali modelli include Go?", "go.faq.a2": - "Go include GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7, con limiti generosi e accesso affidabile.", + "Go include GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7, con limiti generosi e accesso affidabile.", "go.faq.q3": "Go è lo stesso di Zen?", "go.faq.a3": - "No. Zen è a consumo, mentre Go inizia a $5 per il primo mese, poi $10/mese, con limiti generosi e accesso affidabile ai modelli open source GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", + "No. Zen è a consumo, mentre Go inizia a $5 per il primo mese, poi $10/mese, con limiti generosi e accesso affidabile ai modelli open source GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7.", "go.faq.q4": "Quanto costa Go?", "go.faq.a4.p1.beforePricing": "Go costa", "go.faq.a4.p1.pricingLink": "$5 il primo mese", @@ -349,7 +349,7 @@ export const dict = { "go.faq.q9": "Qual è la differenza tra i modelli gratuiti e Go?", "go.faq.a9": - "I modelli gratuiti includono Big Pickle più modelli promozionali disponibili al momento, con una quota di 200 richieste/giorno. Go include GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7 con quote di richiesta più elevate applicate su finestre mobili (5 ore, settimanale e mensile), approssimativamente equivalenti a $12 ogni 5 ore, $30 a settimana e $60 al mese (il conteggio effettivo delle richieste varia in base al modello e all'utilizzo).", + "I modelli gratuiti includono Big Pickle più modelli promozionali disponibili al momento, con una quota di 200 richieste/giorno. Go include GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 e MiniMax M2.7 con quote di richiesta più elevate applicate su finestre mobili (5 ore, settimanale e mensile), approssimativamente equivalenti a $12 ogni 5 ore, $30 a settimana e $60 al mese (il conteggio effettivo delle richieste varia in base al modello e all'utilizzo).", "zen.api.error.rateLimitExceeded": "Limite di richieste superato. Riprova più tardi.", "zen.api.error.modelNotSupported": "Modello {{model}} non supportato", diff --git a/packages/console/app/src/i18n/ja.ts b/packages/console/app/src/i18n/ja.ts index be919d68e8..16fecce6d2 100644 --- a/packages/console/app/src/i18n/ja.ts +++ b/packages/console/app/src/i18n/ja.ts @@ -250,7 +250,7 @@ export const dict = { "go.title": "OpenCode Go | すべての人のための低価格なコーディングモデル", "go.meta.description": - "Goは最初の月$5、その後$10/月で、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7に対して5時間のゆとりあるリクエスト上限があります。", + "Goは最初の月$5、その後$10/月で、GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7に対して5時間のゆとりあるリクエスト上限があります。", "go.hero.title": "すべての人のための低価格なコーディングモデル", "go.hero.body": "Goは、世界中のプログラマーにエージェント型コーディングをもたらします。最も高性能なオープンソースモデルへの十分な制限と安定したアクセスを提供し、コストや可用性を気にすることなく強力なエージェントで構築できます。", @@ -299,7 +299,7 @@ export const dict = { "go.problem.item1": "低価格なサブスクリプション料金", "go.problem.item2": "十分な制限と安定したアクセス", "go.problem.item3": "できるだけ多くのプログラマーのために構築", - "go.problem.item4": "GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7を含む", + "go.problem.item4": "GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7を含む", "go.how.title": "Goの仕組み", "go.how.body": "Goは最初の月$5、その後$10/月で始まります。OpenCodeまたは任意のエージェントで使えます。", "go.how.step1.title": "アカウントを作成", @@ -322,10 +322,10 @@ export const dict = { "Goは、エージェント型コーディングのための有能なオープンソースモデルへの安定したアクセスを提供する低価格なサブスクリプションです。", "go.faq.q2": "Goにはどのモデルが含まれますか?", "go.faq.a2": - "Goには、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7が含まれており、十分な制限と安定したアクセスが提供されます。", + "Goには、GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7が含まれており、十分な制限と安定したアクセスが提供されます。", "go.faq.q3": "GoはZenと同じですか?", "go.faq.a3": - "いいえ。Zenは従量課金制ですが、Goは最初の月$5、その後$10/月で始まり、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7のオープンソースモデルに対して、ゆとりある上限と信頼できるアクセスを提供します。", + "いいえ。Zenは従量課金制ですが、Goは最初の月$5、その後$10/月で始まり、GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7のオープンソースモデルに対して、ゆとりある上限と信頼できるアクセスを提供します。", "go.faq.q4": "Goの料金は?", "go.faq.a4.p1.beforePricing": "Goは", "go.faq.a4.p1.pricingLink": "最初の月$5", @@ -349,7 +349,7 @@ export const dict = { "go.faq.q9": "無料モデルとGoの違いは何ですか?", "go.faq.a9": - "無料モデルにはBig Pickleと、その時点で利用可能なプロモーションモデルが含まれ、1日200リクエストの制限があります。GoにはGLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7が含まれ、ローリングウィンドウ(5時間、週間、月間)全体でより高いリクエスト制限が適用されます。これは概算で5時間あたり$12、週間$30、月間$60相当です(実際のリクエスト数はモデルと使用状況により異なります)。", + "無料モデルにはBig Pickleと、その時点で利用可能なプロモーションモデルが含まれ、1日200リクエストの制限があります。GoにはGLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5、MiniMax M2.7が含まれ、ローリングウィンドウ(5時間、週間、月間)全体でより高いリクエスト制限が適用されます。これは概算で5時間あたり$12、週間$30、月間$60相当です(実際のリクエスト数はモデルと使用状況により異なります)。", "zen.api.error.rateLimitExceeded": "レート制限を超えました。後でもう一度お試しください。", "zen.api.error.modelNotSupported": "モデル {{model}} はサポートされていません", diff --git a/packages/console/app/src/i18n/ko.ts b/packages/console/app/src/i18n/ko.ts index a99a45bbd2..11e76470d1 100644 --- a/packages/console/app/src/i18n/ko.ts +++ b/packages/console/app/src/i18n/ko.ts @@ -247,7 +247,7 @@ export const dict = { "go.title": "OpenCode Go | 모두를 위한 저비용 코딩 모델", "go.meta.description": - "Go는 첫 달 $5, 이후 $10/월로 시작하며, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7에 대해 넉넉한 5시간 요청 한도를 제공합니다.", + "Go는 첫 달 $5, 이후 $10/월로 시작하며, GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7에 대해 넉넉한 5시간 요청 한도를 제공합니다.", "go.hero.title": "모두를 위한 저비용 코딩 모델", "go.hero.body": "Go는 전 세계 프로그래머들에게 에이전트 코딩을 제공합니다. 가장 유능한 오픈 소스 모델에 대한 넉넉한 한도와 안정적인 액세스를 제공하므로, 비용이나 가용성 걱정 없이 강력한 에이전트로 빌드할 수 있습니다.", @@ -296,7 +296,7 @@ export const dict = { "go.problem.item1": "저렴한 구독 가격", "go.problem.item2": "넉넉한 한도와 안정적인 액세스", "go.problem.item3": "가능한 한 많은 프로그래머를 위해 제작됨", - "go.problem.item4": "GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7 포함", + "go.problem.item4": "GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7 포함", "go.how.title": "Go 작동 방식", "go.how.body": "Go는 첫 달 $5, 이후 $10/월로 시작합니다. OpenCode 또는 어떤 에이전트와도 함께 사용할 수 있습니다.", "go.how.step1.title": "계정 생성", @@ -318,10 +318,10 @@ export const dict = { "go.faq.a1": "Go는 에이전트 코딩을 위한 유능한 오픈 소스 모델에 대해 안정적인 액세스를 제공하는 저비용 구독입니다.", "go.faq.q2": "Go에는 어떤 모델이 포함되나요?", "go.faq.a2": - "Go에는 넉넉한 한도와 안정적인 액세스를 제공하는 GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7가 포함됩니다.", + "Go에는 넉넉한 한도와 안정적인 액세스를 제공하는 GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7가 포함됩니다.", "go.faq.q3": "Go는 Zen과 같은가요?", "go.faq.a3": - "아니요. Zen은 종량제인 반면, Go는 첫 달 $5, 이후 $10/월로 시작하며, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7 오픈 소스 모델에 대한 넉넉한 한도와 안정적인 액세스를 제공합니다.", + "아니요. Zen은 종량제인 반면, Go는 첫 달 $5, 이후 $10/월로 시작하며, GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7 오픈 소스 모델에 대한 넉넉한 한도와 안정적인 액세스를 제공합니다.", "go.faq.q4": "Go 비용은 얼마인가요?", "go.faq.a4.p1.beforePricing": "Go 비용은", "go.faq.a4.p1.pricingLink": "첫 달 $5", @@ -344,7 +344,7 @@ export const dict = { "go.faq.q9": "무료 모델과 Go의 차이점은 무엇인가요?", "go.faq.a9": - "무료 모델에는 Big Pickle과 당시 사용 가능한 프로모션 모델이 포함되며, 하루 200회 요청 할당량이 적용됩니다. Go는 GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7를 포함하며, 롤링 윈도우(5시간, 주간, 월간)에 걸쳐 더 높은 요청 할당량을 적용합니다. 이는 대략 5시간당 $12, 주당 $30, 월 $60에 해당합니다(실제 요청 수는 모델 및 사용량에 따라 다름).", + "무료 모델에는 Big Pickle과 당시 사용 가능한 프로모션 모델이 포함되며, 하루 200회 요청 할당량이 적용됩니다. Go는 GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5, MiniMax M2.7를 포함하며, 롤링 윈도우(5시간, 주간, 월간)에 걸쳐 더 높은 요청 할당량을 적용합니다. 이는 대략 5시간당 $12, 주당 $30, 월 $60에 해당합니다(실제 요청 수는 모델 및 사용량에 따라 다름).", "zen.api.error.rateLimitExceeded": "속도 제한을 초과했습니다. 나중에 다시 시도해 주세요.", "zen.api.error.modelNotSupported": "{{model}} 모델은 지원되지 않습니다", diff --git a/packages/console/app/src/i18n/no.ts b/packages/console/app/src/i18n/no.ts index 4cacb49d8a..282208e5e1 100644 --- a/packages/console/app/src/i18n/no.ts +++ b/packages/console/app/src/i18n/no.ts @@ -251,7 +251,7 @@ export const dict = { "go.title": "OpenCode Go | Rimelige kodemodeller for alle", "go.meta.description": - "Go starter på $5 for den første måneden, deretter $10/måned, med sjenerøse 5-timers forespørselsgrenser for GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", + "Go starter på $5 for den første måneden, deretter $10/måned, med sjenerøse 5-timers forespørselsgrenser for GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", "go.hero.title": "Rimelige kodemodeller for alle", "go.hero.body": "Go bringer agent-koding til programmerere over hele verden. Med rause grenser og pålitelig tilgang til de mest kapable åpen kildekode-modellene, kan du bygge med kraftige agenter uten å bekymre deg for kostnader eller tilgjengelighet.", @@ -299,7 +299,7 @@ export const dict = { "go.problem.item1": "Rimelig abonnementspris", "go.problem.item2": "Rause grenser og pålitelig tilgang", "go.problem.item3": "Bygget for så mange programmerere som mulig", - "go.problem.item4": "Inkluderer GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7", + "go.problem.item4": "Inkluderer GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7", "go.how.title": "Hvordan Go fungerer", "go.how.body": "Go starter på $5 for den første måneden, deretter $10/måned. Du kan bruke det med OpenCode eller hvilken som helst agent.", @@ -323,10 +323,10 @@ export const dict = { "Go er et rimelig abonnement som gir deg pålitelig tilgang til kapable åpen kildekode-modeller for agent-koding.", "go.faq.q2": "Hvilke modeller inkluderer Go?", "go.faq.a2": - "Go inkluderer GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7, med rause grenser og pålitelig tilgang.", + "Go inkluderer GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7, med rause grenser og pålitelig tilgang.", "go.faq.q3": "Er Go det samme som Zen?", "go.faq.a3": - "Nei. Zen er betaling etter bruk, mens Go starter på $5 for den første måneden, deretter $10/måned, med sjenerøse grenser og pålitelig tilgang til åpen kildekode-modellene GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", + "Nei. Zen er betaling etter bruk, mens Go starter på $5 for den første måneden, deretter $10/måned, med sjenerøse grenser og pålitelig tilgang til åpen kildekode-modellene GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7.", "go.faq.q4": "Hva koster Go?", "go.faq.a4.p1.beforePricing": "Go koster", "go.faq.a4.p1.pricingLink": "$5 første måned", @@ -350,7 +350,7 @@ export const dict = { "go.faq.q9": "Hva er forskjellen mellom gratis modeller og Go?", "go.faq.a9": - "Gratis modeller inkluderer Big Pickle pluss kampanjemodeller tilgjengelig på det tidspunktet, med en kvote på 200 forespørsler/dag. Go inkluderer GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7 med høyere kvoter håndhevet over rullerende vinduer (5 timer, ukentlig og månedlig), omtrent tilsvarende $12 per 5 timer, $30 per uke og $60 per måned (faktiske forespørselsantall varierer etter modell og bruk).", + "Gratis modeller inkluderer Big Pickle pluss kampanjemodeller tilgjengelig på det tidspunktet, med en kvote på 200 forespørsler/dag. Go inkluderer GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 og MiniMax M2.7 med høyere kvoter håndhevet over rullerende vinduer (5 timer, ukentlig og månedlig), omtrent tilsvarende $12 per 5 timer, $30 per uke og $60 per måned (faktiske forespørselsantall varierer etter modell og bruk).", "zen.api.error.rateLimitExceeded": "Rate limit overskredet. Vennligst prøv igjen senere.", "zen.api.error.modelNotSupported": "Modell {{model}} støttes ikke", diff --git a/packages/console/app/src/i18n/pl.ts b/packages/console/app/src/i18n/pl.ts index 4b0e250741..ffdd8f5cbd 100644 --- a/packages/console/app/src/i18n/pl.ts +++ b/packages/console/app/src/i18n/pl.ts @@ -252,7 +252,7 @@ export const dict = { "go.title": "OpenCode Go | Niskokosztowe modele do kodowania dla każdego", "go.meta.description": - "Go zaczyna się od $5 za pierwszy miesiąc, potem $10/miesiąc, z hojnymi 5-godzinnymi limitami zapytań dla GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7.", + "Go zaczyna się od $5 za pierwszy miesiąc, potem $10/miesiąc, z hojnymi 5-godzinnymi limitami zapytań dla GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7.", "go.hero.title": "Niskokosztowe modele do kodowania dla każdego", "go.hero.body": "Go udostępnia programowanie z agentami programistom na całym świecie. Oferuje hojne limity i niezawodny dostęp do najzdolniejszych modeli open source, dzięki czemu możesz budować za pomocą potężnych agentów, nie martwiąc się o koszty czy dostępność.", @@ -300,7 +300,7 @@ export const dict = { "go.problem.item1": "Niskokosztowa cena subskrypcji", "go.problem.item2": "Hojne limity i niezawodny dostęp", "go.problem.item3": "Stworzony dla jak największej liczby programistów", - "go.problem.item4": "Zawiera GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7", + "go.problem.item4": "Zawiera GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7", "go.how.title": "Jak działa Go", "go.how.body": "Go zaczyna się od $5 za pierwszy miesiąc, potem $10/miesiąc. Możesz go używać z OpenCode lub dowolnym agentem.", @@ -324,10 +324,10 @@ export const dict = { "Go to niskokosztowa subskrypcja, która daje niezawodny dostęp do zdolnych modeli open source dla agentów kodujących.", "go.faq.q2": "Jakie modele zawiera Go?", "go.faq.a2": - "Go zawiera GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7, z hojnymi limitami i niezawodnym dostępem.", + "Go zawiera GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7, z hojnymi limitami i niezawodnym dostępem.", "go.faq.q3": "Czy Go to to samo co Zen?", "go.faq.a3": - "Nie. Zen to model płatności za użycie, podczas gdy Go zaczyna się od $5 za pierwszy miesiąc, potem $10/miesiąc, z hojnymi limitami i niezawodnym dostępem do modeli open source GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7.", + "Nie. Zen to model płatności za użycie, podczas gdy Go zaczyna się od $5 za pierwszy miesiąc, potem $10/miesiąc, z hojnymi limitami i niezawodnym dostępem do modeli open source GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7.", "go.faq.q4": "Ile kosztuje Go?", "go.faq.a4.p1.beforePricing": "Go kosztuje", "go.faq.a4.p1.pricingLink": "$5 za pierwszy miesiąc", @@ -351,7 +351,7 @@ export const dict = { "go.faq.q9": "Jaka jest różnica między darmowymi modelami a Go?", "go.faq.a9": - "Darmowe modele obejmują Big Pickle oraz modele promocyjne dostępne w danym momencie, z limitem 200 zapytań/dzień. Go zawiera GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7 z wyższymi limitami zapytań egzekwowanymi w oknach kroczących (5-godzinnych, tygodniowych i miesięcznych), w przybliżeniu równoważnymi $12 na 5 godzin, $30 tygodniowo i $60 miesięcznie (rzeczywista liczba zapytań zależy od modelu i użycia).", + "Darmowe modele obejmują Big Pickle oraz modele promocyjne dostępne w danym momencie, z limitem 200 zapytań/dzień. Go zawiera GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 i MiniMax M2.7 z wyższymi limitami zapytań egzekwowanymi w oknach kroczących (5-godzinnych, tygodniowych i miesięcznych), w przybliżeniu równoważnymi $12 na 5 godzin, $30 tygodniowo i $60 miesięcznie (rzeczywista liczba zapytań zależy od modelu i użycia).", "zen.api.error.rateLimitExceeded": "Przekroczono limit zapytań. Spróbuj ponownie później.", "zen.api.error.modelNotSupported": "Model {{model}} nie jest obsługiwany", diff --git a/packages/console/app/src/i18n/ru.ts b/packages/console/app/src/i18n/ru.ts index faa774ea07..8864b6a272 100644 --- a/packages/console/app/src/i18n/ru.ts +++ b/packages/console/app/src/i18n/ru.ts @@ -255,7 +255,7 @@ export const dict = { "go.title": "OpenCode Go | Недорогие модели для кодинга для всех", "go.meta.description": - "Go начинается с $5 за первый месяц, затем $10/месяц, с щедрыми лимитами запросов за 5 часов для GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7.", + "Go начинается с $5 за первый месяц, затем $10/месяц, с щедрыми лимитами запросов за 5 часов для GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7.", "go.hero.title": "Недорогие модели для кодинга для всех", "go.hero.body": "Go открывает доступ к агентам-программистам разработчикам по всему миру. Предлагая щедрые лимиты и надежный доступ к наиболее способным моделям с открытым исходным кодом, вы можете создавать проекты с мощными агентами, не беспокоясь о затратах или доступности.", @@ -304,7 +304,7 @@ export const dict = { "go.problem.item1": "Недорогая подписка", "go.problem.item2": "Щедрые лимиты и надежный доступ", "go.problem.item3": "Создан для максимального числа программистов", - "go.problem.item4": "Включает GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7", + "go.problem.item4": "Включает GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7", "go.how.title": "Как работает Go", "go.how.body": "Go начинается с $5 за первый месяц, затем $10/месяц. Вы можете использовать его с OpenCode или любым агентом.", @@ -328,10 +328,10 @@ export const dict = { "Go — это недорогая подписка, дающая надежный доступ к мощным моделям с открытым исходным кодом для агентов-программистов.", "go.faq.q2": "Какие модели включает Go?", "go.faq.a2": - "Go включает GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7, с щедрыми лимитами и надежным доступом.", + "Go включает GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7, с щедрыми лимитами и надежным доступом.", "go.faq.q3": "Go — это то же самое, что и Zen?", "go.faq.a3": - "Нет. Zen - это оплата по мере использования, в то время как Go начинается с $5 за первый месяц, затем $10/месяц, с щедрыми лимитами и надежным доступом к моделям с открытым исходным кодом GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7.", + "Нет. Zen - это оплата по мере использования, в то время как Go начинается с $5 за первый месяц, затем $10/месяц, с щедрыми лимитами и надежным доступом к моделям с открытым исходным кодом GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7.", "go.faq.q4": "Сколько стоит Go?", "go.faq.a4.p1.beforePricing": "Go стоит", "go.faq.a4.p1.pricingLink": "$5 за первый месяц", @@ -355,7 +355,7 @@ export const dict = { "go.faq.q9": "В чем разница между бесплатными моделями и Go?", "go.faq.a9": - "Бесплатные модели включают Big Pickle плюс промо-модели, доступные на данный момент, с квотой 200 запросов/день. Go включает GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7 с более высокими квотами запросов, применяемыми в скользящих окнах (5 часов, неделя и месяц), что примерно эквивалентно $12 за 5 часов, $30 в неделю и $60 в месяц (фактическое количество запросов зависит от модели и использования).", + "Бесплатные модели включают Big Pickle плюс промо-модели, доступные на данный момент, с квотой 200 запросов/день. Go включает GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 и MiniMax M2.7 с более высокими квотами запросов, применяемыми в скользящих окнах (5 часов, неделя и месяц), что примерно эквивалентно $12 за 5 часов, $30 в неделю и $60 в месяц (фактическое количество запросов зависит от модели и использования).", "zen.api.error.rateLimitExceeded": "Превышен лимит запросов. Пожалуйста, попробуйте позже.", "zen.api.error.modelNotSupported": "Модель {{model}} не поддерживается", diff --git a/packages/console/app/src/i18n/th.ts b/packages/console/app/src/i18n/th.ts index d70f4c4f6f..daf213eac7 100644 --- a/packages/console/app/src/i18n/th.ts +++ b/packages/console/app/src/i18n/th.ts @@ -250,7 +250,7 @@ export const dict = { "go.title": "OpenCode Go | โมเดลเขียนโค้ดราคาประหยัดสำหรับทุกคน", "go.meta.description": - "Go เริ่มต้นที่ $5 สำหรับเดือนแรก จากนั้น $10/เดือน พร้อมขีดจำกัดคำขอ 5 ชั่วโมงที่เอื้อเฟื้อสำหรับ GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7", + "Go เริ่มต้นที่ $5 สำหรับเดือนแรก จากนั้น $10/เดือน พร้อมขีดจำกัดคำขอ 5 ชั่วโมงที่เอื้อเฟื้อสำหรับ GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7", "go.hero.title": "โมเดลเขียนโค้ดราคาประหยัดสำหรับทุกคน", "go.hero.body": "Go นำการเขียนโค้ดแบบเอเจนต์มาสู่นักเขียนโปรแกรมทั่วโลก เสนอขีดจำกัดที่กว้างขวางและการเข้าถึงโมเดลโอเพนซอร์สที่มีความสามารถสูงสุดได้อย่างน่าเชื่อถือ เพื่อให้คุณสามารถสร้างสรรค์ด้วยเอเจนต์ที่ทรงพลังโดยไม่ต้องกังวลเรื่องค่าใช้จ่ายหรือความพร้อมใช้งาน", @@ -297,7 +297,7 @@ export const dict = { "go.problem.item1": "ราคาการสมัครสมาชิกที่ต่ำ", "go.problem.item2": "ขีดจำกัดที่กว้างขวางและการเข้าถึงที่เชื่อถือได้", "go.problem.item3": "สร้างขึ้นเพื่อโปรแกรมเมอร์จำนวนมากที่สุดเท่าที่จะเป็นไปได้", - "go.problem.item4": "รวมถึง GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7", + "go.problem.item4": "รวมถึง GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7", "go.how.title": "Go ทำงานอย่างไร", "go.how.body": "Go เริ่มต้นที่ $5 สำหรับเดือนแรก จากนั้น $10/เดือน คุณสามารถใช้กับ OpenCode หรือเอเจนต์ใดก็ได้", "go.how.step1.title": "สร้างบัญชี", @@ -320,10 +320,10 @@ export const dict = { "Go คือการสมัครสมาชิกราคาประหยัดที่ให้คุณเข้าถึงโมเดลโอเพนซอร์สที่มีความสามารถสำหรับการเขียนโค้ดแบบเอเจนต์ได้อย่างน่าเชื่อถือ", "go.faq.q2": "Go รวมโมเดลอะไรบ้าง?", "go.faq.a2": - "Go รวมถึง GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7 พร้อมขีดจำกัดที่กว้างขวางและการเข้าถึงที่เชื่อถือได้", + "Go รวมถึง GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7 พร้อมขีดจำกัดที่กว้างขวางและการเข้าถึงที่เชื่อถือได้", "go.faq.q3": "Go เหมือนกับ Zen หรือไม่?", "go.faq.a3": - "ไม่ Zen เป็นแบบจ่ายตามการใช้งาน ในขณะที่ Go เริ่มต้นที่ $5 สำหรับเดือนแรก จากนั้น $10/เดือน พร้อมขีดจำกัดที่เอื้อเฟื้อและการเข้าถึงโมเดลโอเพนซอร์ส GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7 อย่างเชื่อถือได้", + "ไม่ Zen เป็นแบบจ่ายตามการใช้งาน ในขณะที่ Go เริ่มต้นที่ $5 สำหรับเดือนแรก จากนั้น $10/เดือน พร้อมขีดจำกัดที่เอื้อเฟื้อและการเข้าถึงโมเดลโอเพนซอร์ส GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7 อย่างเชื่อถือได้", "go.faq.q4": "Go ราคาเท่าไหร่?", "go.faq.a4.p1.beforePricing": "Go ราคา", "go.faq.a4.p1.pricingLink": "$5 เดือนแรก", @@ -346,7 +346,7 @@ export const dict = { "go.faq.q9": "ความแตกต่างระหว่างโมเดลฟรีและ Go คืออะไร?", "go.faq.a9": - "โมเดลฟรีรวมถึง Big Pickle บวกกับโมเดลโปรโมชั่นที่มีให้ในขณะนั้น ด้วยโควต้า 200 คำขอ/วัน Go รวมถึง GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7 ที่มีโควต้าคำขอสูงกว่า ซึ่งบังคับใช้ผ่านช่วงเวลาหมุนเวียน (5 ชั่วโมง, รายสัปดาห์ และรายเดือน) เทียบเท่าประมาณ $12 ต่อ 5 ชั่วโมง, $30 ต่อสัปดาห์ และ $60 ต่อเดือน (จำนวนคำขอจริงจะแตกต่างกันไปตามโมเดลและการใช้งาน)", + "โมเดลฟรีรวมถึง Big Pickle บวกกับโมเดลโปรโมชั่นที่มีให้ในขณะนั้น ด้วยโควต้า 200 คำขอ/วัน Go รวมถึง GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 และ MiniMax M2.7 ที่มีโควต้าคำขอสูงกว่า ซึ่งบังคับใช้ผ่านช่วงเวลาหมุนเวียน (5 ชั่วโมง, รายสัปดาห์ และรายเดือน) เทียบเท่าประมาณ $12 ต่อ 5 ชั่วโมง, $30 ต่อสัปดาห์ และ $60 ต่อเดือน (จำนวนคำขอจริงจะแตกต่างกันไปตามโมเดลและการใช้งาน)", "zen.api.error.rateLimitExceeded": "เกินขีดจำกัดอัตราการใช้งาน กรุณาลองใหม่ในภายหลัง", "zen.api.error.modelNotSupported": "ไม่รองรับโมเดล {{model}}", diff --git a/packages/console/app/src/i18n/tr.ts b/packages/console/app/src/i18n/tr.ts index 21efe463b2..8eaafe207b 100644 --- a/packages/console/app/src/i18n/tr.ts +++ b/packages/console/app/src/i18n/tr.ts @@ -253,7 +253,7 @@ export const dict = { "go.title": "OpenCode Go | Herkes için düşük maliyetli kodlama modelleri", "go.meta.description": - "Go ilk ay $5, sonrasında ayda 10$ fiyatıyla başlar; GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 için cömert 5 saatlik istek limitleri sunar.", + "Go ilk ay $5, sonrasında ayda 10$ fiyatıyla başlar; GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 için cömert 5 saatlik istek limitleri sunar.", "go.hero.title": "Herkes için düşük maliyetli kodlama modelleri", "go.hero.body": "Go, dünya çapındaki programcılara ajan tabanlı kodlama getiriyor. En yetenekli açık kaynaklı modellere cömert limitler ve güvenilir erişim sunarak, maliyet veya erişilebilirlik konusunda endişelenmeden güçlü ajanlarla geliştirme yapmanızı sağlar.", @@ -302,7 +302,7 @@ export const dict = { "go.problem.item1": "Düşük maliyetli abonelik fiyatlandırması", "go.problem.item2": "Cömert limitler ve güvenilir erişim", "go.problem.item3": "Mümkün olduğunca çok programcı için geliştirildi", - "go.problem.item4": "GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 içerir", + "go.problem.item4": "GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 içerir", "go.how.title": "Go nasıl çalışır?", "go.how.body": "Go ilk ay $5, sonrasında ayda 10$ fiyatıyla başlar. OpenCode veya herhangi bir ajanla kullanabilirsiniz.", @@ -326,10 +326,10 @@ export const dict = { "Go, ajan tabanlı kodlama için yetenekli açık kaynaklı modellere güvenilir erişim sağlayan düşük maliyetli bir aboneliktir.", "go.faq.q2": "Go hangi modelleri içerir?", "go.faq.a2": - "Go, cömert limitler ve güvenilir erişim ile GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 modellerini içerir.", + "Go, cömert limitler ve güvenilir erişim ile GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 modellerini içerir.", "go.faq.q3": "Go, Zen ile aynı mı?", "go.faq.a3": - "Hayır. Zen kullandıkça öde modelidir, Go ise ilk ay $5, sonrasında ayda 10$ fiyatıyla başlar; GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 açık kaynak modellerine cömert limitler ve güvenilir erişim sunar.", + "Hayır. Zen kullandıkça öde modelidir, Go ise ilk ay $5, sonrasında ayda 10$ fiyatıyla başlar; GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 açık kaynak modellerine cömert limitler ve güvenilir erişim sunar.", "go.faq.q4": "Go ne kadar?", "go.faq.a4.p1.beforePricing": "Go'nun maliyeti", "go.faq.a4.p1.pricingLink": "İlk ay $5", @@ -353,7 +353,7 @@ export const dict = { "go.faq.q9": "Ücretsiz modeller ve Go arasındaki fark nedir?", "go.faq.a9": - "Ücretsiz modeller, günlük 200 istek kotası ile Big Pickle ve o sırada mevcut olan promosyonel modelleri içerir. Go ise GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 modellerini; yuvarlanan pencereler (5 saatlik, haftalık ve aylık) üzerinden uygulanan daha yüksek istek kotalarıyla içerir. Bu kotalar kabaca her 5 saatte 12$, haftada 30$ ve ayda 60$ değerine eşdeğerdir (gerçek istek sayıları modele ve kullanıma göre değişir).", + "Ücretsiz modeller, günlük 200 istek kotası ile Big Pickle ve o sırada mevcut olan promosyonel modelleri içerir. Go ise GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 ve MiniMax M2.7 modellerini; yuvarlanan pencereler (5 saatlik, haftalık ve aylık) üzerinden uygulanan daha yüksek istek kotalarıyla içerir. Bu kotalar kabaca her 5 saatte 12$, haftada 30$ ve ayda 60$ değerine eşdeğerdir (gerçek istek sayıları modele ve kullanıma göre değişir).", "zen.api.error.rateLimitExceeded": "İstek limiti aşıldı. Lütfen daha sonra tekrar deneyin.", "zen.api.error.modelNotSupported": "{{model}} modeli desteklenmiyor", diff --git a/packages/console/app/src/i18n/zh.ts b/packages/console/app/src/i18n/zh.ts index 49498bfd74..bfbdd2702f 100644 --- a/packages/console/app/src/i18n/zh.ts +++ b/packages/console/app/src/i18n/zh.ts @@ -241,7 +241,7 @@ export const dict = { "go.title": "OpenCode Go | 人人可用的低成本编程模型", "go.meta.description": - "Go 首月 $5,之后 $10/月,提供对 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 的 5 小时充裕请求额度。", + "Go 首月 $5,之后 $10/月,提供对 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 的 5 小时充裕请求额度。", "go.hero.title": "人人可用的低成本编程模型", "go.hero.body": "Go 将代理编程带给全世界的程序员。提供充裕的限额和对最强大的开源模型的可靠访问,让您可以利用强大的代理进行构建,而无需担心成本或可用性。", @@ -288,7 +288,7 @@ export const dict = { "go.problem.item1": "低成本订阅定价", "go.problem.item2": "充裕的限额和可靠的访问", "go.problem.item3": "为尽可能多的程序员打造", - "go.problem.item4": "包含 GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 和 MiniMax M2.7", + "go.problem.item4": "包含 GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 和 MiniMax M2.7", "go.how.title": "Go 如何工作", "go.how.body": "Go 起价为首月 $5,之后 $10/月。您可以将其与 OpenCode 或任何代理搭配使用。", "go.how.step1.title": "创建账户", @@ -308,10 +308,10 @@ export const dict = { "go.faq.a1": "Go 是一项低成本订阅服务,为您提供对强大的开源模型的可靠访问,用于代理编程。", "go.faq.q2": "Go 包含哪些模型?", "go.faq.a2": - "Go 包含 GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 和 MiniMax M2.7,并提供充裕的限额和可靠的访问。", + "Go 包含 GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 和 MiniMax M2.7,并提供充裕的限额和可靠的访问。", "go.faq.q3": "Go 和 Zen 一样吗?", "go.faq.a3": - "不。Zen 是按量付费,而 Go 首月 $5,之后 $10/月,提供充裕的额度,并可可靠地访问 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 等开源模型。", + "不。Zen 是按量付费,而 Go 首月 $5,之后 $10/月,提供充裕的额度,并可可靠地访问 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 等开源模型。", "go.faq.q4": "Go 多少钱?", "go.faq.a4.p1.beforePricing": "Go 费用为", "go.faq.a4.p1.pricingLink": "首月 $5", @@ -333,7 +333,7 @@ export const dict = { "go.faq.q9": "免费模型和 Go 之间的区别是什么?", "go.faq.a9": - "免费模型包含 Big Pickle 加上当时可用的促销模型,每天有 200 次请求的配额。Go 包含 GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 和 MiniMax M2.7,并在滚动窗口(5 小时、每周和每月)内执行更高的请求配额,大致相当于每 5 小时 $12、每周 $30 和每月 $60(实际请求计数因模型和使用情况而异)。", + "免费模型包含 Big Pickle 加上当时可用的促销模型,每天有 200 次请求的配额。Go 包含 GLM-5.1, GLM-5, Kimi K2.5, MiMo-V2-Pro, MiMo-V2-Omni, MiniMax M2.5 和 MiniMax M2.7,并在滚动窗口(5 小时、每周和每月)内执行更高的请求配额,大致相当于每 5 小时 $12、每周 $30 和每月 $60(实际请求计数因模型和使用情况而异)。", "zen.api.error.rateLimitExceeded": "超出速率限制。请稍后重试。", "zen.api.error.modelNotSupported": "不支持模型 {{model}}", diff --git a/packages/console/app/src/i18n/zht.ts b/packages/console/app/src/i18n/zht.ts index 0dbbdd4a71..0a44f4fa04 100644 --- a/packages/console/app/src/i18n/zht.ts +++ b/packages/console/app/src/i18n/zht.ts @@ -241,7 +241,7 @@ export const dict = { "go.title": "OpenCode Go | 低成本全民編碼模型", "go.meta.description": - "Go 首月 $5,之後 $10/月,提供對 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 的 5 小時充裕請求額度。", + "Go 首月 $5,之後 $10/月,提供對 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 的 5 小時充裕請求額度。", "go.hero.title": "低成本全民編碼模型", "go.hero.body": "Go 將代理編碼帶給全世界的程式設計師。提供寬裕的限額以及對最強大開源模型的穩定存取,讓你可以使用強大的代理進行構建,而無需擔心成本或可用性。", @@ -288,7 +288,7 @@ export const dict = { "go.problem.item1": "低成本訂閱定價", "go.problem.item2": "寬裕的限額與穩定存取", "go.problem.item3": "專為盡可能多的程式設計師打造", - "go.problem.item4": "包含 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 與 MiniMax M2.7", + "go.problem.item4": "包含 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 與 MiniMax M2.7", "go.how.title": "Go 如何運作", "go.how.body": "Go 起價為首月 $5,之後 $10/月。您可以將其與 OpenCode 或任何代理搭配使用。", "go.how.step1.title": "建立帳號", @@ -308,10 +308,10 @@ export const dict = { "go.faq.a1": "Go 是一個低成本訂閱方案,讓你穩定存取強大的開源模型以進行代理編碼。", "go.faq.q2": "Go 包含哪些模型?", "go.faq.a2": - "Go 包含 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 與 MiniMax M2.7,並提供寬裕的限額與穩定存取。", + "Go 包含 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 與 MiniMax M2.7,並提供寬裕的限額與穩定存取。", "go.faq.q3": "Go 與 Zen 一樣嗎?", "go.faq.a3": - "不。Zen 是按量付費,而 Go 首月 $5,之後 $10/月,提供充裕的額度,並可可靠地存取 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 等開源模型。", + "不。Zen 是按量付費,而 Go 首月 $5,之後 $10/月,提供充裕的額度,並可可靠地存取 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 和 MiniMax M2.7 等開源模型。", "go.faq.q4": "Go 費用是多少?", "go.faq.a4.p1.beforePricing": "Go 費用為", "go.faq.a4.p1.pricingLink": "首月 $5", @@ -333,7 +333,7 @@ export const dict = { "go.faq.q9": "免費模型與 Go 有什麼區別?", "go.faq.a9": - "免費模型包括 Big Pickle 以及當時可用的促銷模型,配額為 200 次請求/天。Go 包括 GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 與 MiniMax M2.7,並在滾動視窗(5 小時、每週和每月)內執行更高的請求配額,大約相當於每 5 小時 $12、每週 $30 和每月 $60(實際請求數因模型和使用情況而異)。", + "免費模型包括 Big Pickle 以及當時可用的促銷模型,配額為 200 次請求/天。Go 包括 GLM-5.1、GLM-5、Kimi K2.5、MiMo-V2-Pro、MiMo-V2-Omni、MiniMax M2.5 與 MiniMax M2.7,並在滾動視窗(5 小時、每週和每月)內執行更高的請求配額,大約相當於每 5 小時 $12、每週 $30 和每月 $60(實際請求數因模型和使用情況而異)。", "zen.api.error.rateLimitExceeded": "超出頻率限制。請稍後再試。", "zen.api.error.modelNotSupported": "不支援模型 {{model}}", diff --git a/packages/console/app/src/routes/go/index.tsx b/packages/console/app/src/routes/go/index.tsx index ee4214fc5e..e4628fe110 100644 --- a/packages/console/app/src/routes/go/index.tsx +++ b/packages/console/app/src/routes/go/index.tsx @@ -45,16 +45,16 @@ function LimitsGraph(props: { href: string }) { const free = 200 const models = [ - { id: "glm", name: "GLM-5", req: 1150, d: "120ms" }, - { id: "kimi", name: "Kimi K2.5", req: 1850, d: "240ms" }, + { id: "glm-5.1", name: "GLM-5.1", req: 880, d: "100ms" }, + { id: "glm-5", name: "GLM-5", req: 1150, d: "120ms" }, { id: "mimo-v2-pro", name: "MiMo-V2-Pro", req: 1290, d: "150ms" }, - { id: "mimo-v2-omni", name: "MiMo-V2-Omni", req: 2150, d: "270ms" }, + { id: "kimi", name: "Kimi K2.5", req: 1850, d: "240ms" }, { id: "minimax-m2.7", name: "MiniMax M2.7", req: 14000, d: "330ms" }, { id: "minimax-m2.5", name: "MiniMax M2.5", req: 20000, d: "360ms" }, ] const w = 720 - const h = 260 + const h = 270 const left = 40 const right = 60 const top = 18 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 20042ca718..70d6aea7a2 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 @@ -287,6 +287,7 @@ export function LiteSection() {
  • Kimi K2.5
  • GLM-5
  • +
  • GLM-5.1
  • Mimo-V2-Pro
  • Mimo-V2-Omni
  • MiniMax M2.5
  • diff --git a/packages/console/core/package.json b/packages/console/core/package.json index ae5185e116..27bbe65057 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.3.17", + "version": "1.4.0", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index e05a516533..8832403183 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.3.17", + "version": "1.4.0", "$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 63878f7c55..4427d18c91 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.3.17", + "version": "1.4.0", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/desktop-electron/package.json b/packages/desktop-electron/package.json index 2e851d6cf0..66d2144d5d 100644 --- a/packages/desktop-electron/package.json +++ b/packages/desktop-electron/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop-electron", "private": true, - "version": "1.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "homepage": "https://opencode.ai", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index d4a8244468..509661e02a 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index e046366dc9..2f6ebc9f1c 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.3.17", + "version": "1.4.0", "private": true, "type": "module", "license": "MIT", diff --git a/packages/enterprise/src/core/share.ts b/packages/enterprise/src/core/share.ts index c6291b75d2..18fcd7a071 100644 --- a/packages/enterprise/src/core/share.ts +++ b/packages/enterprise/src/core/share.ts @@ -1,4 +1,4 @@ -import { FileDiff, Message, Model, Part, Session } from "@opencode-ai/sdk/v2" +import { Message, Model, Part, Session, SnapshotFileDiff } from "@opencode-ai/sdk/v2" import { fn } from "@opencode-ai/util/fn" import { iife } from "@opencode-ai/util/iife" import z from "zod" @@ -27,7 +27,7 @@ export namespace Share { }), z.object({ type: z.literal("session_diff"), - data: z.custom(), + data: z.custom(), }), z.object({ type: z.literal("model"), diff --git a/packages/enterprise/src/routes/share/[shareID].tsx b/packages/enterprise/src/routes/share/[shareID].tsx index e755ea75a1..edeeaf1ad5 100644 --- a/packages/enterprise/src/routes/share/[shareID].tsx +++ b/packages/enterprise/src/routes/share/[shareID].tsx @@ -1,4 +1,4 @@ -import { FileDiff, Message, Model, Part, Session, SessionStatus, UserMessage } from "@opencode-ai/sdk/v2" +import { Message, Model, Part, Session, SessionStatus, SnapshotFileDiff, UserMessage } from "@opencode-ai/sdk/v2" import { SessionTurn } from "@opencode-ai/ui/session-turn" import { SessionReview } from "@opencode-ai/ui/session-review" import { DataProvider } from "@opencode-ai/ui/context" @@ -51,7 +51,7 @@ const getData = query(async (shareID) => { shareID: string session: Session[] session_diff: { - [sessionID: string]: FileDiff[] + [sessionID: string]: SnapshotFileDiff[] } session_status: { [sessionID: string]: SessionStatus diff --git a/packages/extensions/zed/extension.toml b/packages/extensions/zed/extension.toml index 2c8e827ba7..5562adb4b7 100644 --- a/packages/extensions/zed/extension.toml +++ b/packages/extensions/zed/extension.toml @@ -1,7 +1,7 @@ id = "opencode" name = "OpenCode" description = "The open source coding agent." -version = "1.3.17" +version = "1.4.0" schema_version = 1 authors = ["Anomaly"] repository = "https://github.com/anomalyco/opencode" @@ -11,26 +11,26 @@ name = "OpenCode" icon = "./icons/opencode.svg" [agent_servers.opencode.targets.darwin-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-darwin-arm64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-darwin-arm64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.darwin-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-darwin-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-darwin-x64.zip" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-aarch64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-linux-arm64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-linux-arm64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.linux-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-linux-x64.tar.gz" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-linux-x64.tar.gz" cmd = "./opencode" args = ["acp"] [agent_servers.opencode.targets.windows-x86_64] -archive = "https://github.com/anomalyco/opencode/releases/download/v1.3.17/opencode-windows-x64.zip" +archive = "https://github.com/anomalyco/opencode/releases/download/v1.4.0/opencode-windows-x64.zip" cmd = "./opencode.exe" args = ["acp"] diff --git a/packages/function/package.json b/packages/function/package.json index ae7f1c48d0..f1996f63b4 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.3.17", + "version": "1.4.0", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index b88ba974f2..89496361ae 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.3.17", + "version": "1.4.0", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/opencode/specs/v2.md b/packages/opencode/specs/v2/keymappings.md similarity index 89% rename from packages/opencode/specs/v2.md rename to packages/opencode/specs/v2/keymappings.md index 66b4d2dea4..5b23db7954 100644 --- a/packages/opencode/specs/v2.md +++ b/packages/opencode/specs/v2/keymappings.md @@ -1,8 +1,4 @@ -# 2.0 - -What we would change if we could - -## Keybindings vs. Keymappings +# Keybindings vs. Keymappings Make it `keymappings`, closer to neovim. Can be layered like `abc`. Commands don't define their binding, but have an id that a key can be mapped to like diff --git a/packages/opencode/specs/v2/message-shape.md b/packages/opencode/specs/v2/message-shape.md new file mode 100644 index 0000000000..965498f190 --- /dev/null +++ b/packages/opencode/specs/v2/message-shape.md @@ -0,0 +1,136 @@ +# Message Shape + +Problem: + +- stored messages need enough data to replay and resume a session later +- prompt hooks often just want to append a synthetic user/assistant message +- today that means faking ids, timestamps, and request metadata + +## Option 1: Two Message Shapes + +Keep `User` / `Assistant` for stored history, but clean them up. + +```ts +type User = { + role: "user" + time: { created: number } + request: { + agent: string + model: ModelRef + variant?: string + format?: OutputFormat + system?: string + tools?: Record + } +} + +type Assistant = { + role: "assistant" + run: { agent: string; model: ModelRef; path: { cwd: string; root: string } } + usage: { cost: number; tokens: Tokens } + result: { finish?: string; error?: Error; structured?: unknown; kind: "reply" | "summary" } +} +``` + +Add a separate transient `PromptMessage` for prompt surgery. + +```ts +type PromptMessage = { + role: "user" | "assistant" + parts: PromptPart[] +} +``` + +Plugin hook example: + +```ts +prompt.push({ + role: "user", + parts: [{ type: "text", text: "Summarize the tool output above and continue." }], +}) +``` + +Tradeoff: prompt hooks get easy lightweight messages, but there are now two message shapes. + +## Option 2: Prompt Mutators + +Keep `User` / `Assistant` as the stored history model. + +Prompt hooks do not build messages directly. The runtime gives them prompt mutators. + +```ts +type PromptEditor = { + append(input: { role: "user" | "assistant"; parts: PromptPart[] }): void + prepend(input: { role: "user" | "assistant"; parts: PromptPart[] }): void + appendTo(target: "last-user" | "last-assistant", parts: PromptPart[]): void + insertAfter(messageID: string, input: { role: "user" | "assistant"; parts: PromptPart[] }): void + insertBefore(messageID: string, input: { role: "user" | "assistant"; parts: PromptPart[] }): void +} +``` + +Plugin hook examples: + +```ts +prompt.append({ + role: "user", + parts: [{ type: "text", text: "Summarize the tool output above and continue." }], +}) +``` + +```ts +prompt.appendTo("last-user", [{ type: "text", text: BUILD_SWITCH }]) +``` + +Tradeoff: avoids a second full message type and avoids fake ids/timestamps, but moves more magic into the hook API. + +## Option 3: Separate Turn State + +Move execution settings out of `User` and into a separate turn/request object. + +```ts +type Turn = { + id: string + request: { + agent: string + model: ModelRef + variant?: string + format?: OutputFormat + system?: string + tools?: Record + } +} + +type User = { + role: "user" + turnID: string + time: { created: number } +} + +type Assistant = { + role: "assistant" + turnID: string + usage: { cost: number; tokens: Tokens } + result: { finish?: string; error?: Error; structured?: unknown; kind: "reply" | "summary" } +} +``` + +Examples: + +```ts +const turn = { + request: { + agent: "build", + model: { providerID: "openai", modelID: "gpt-5" }, + }, +} +``` + +```ts +const msg = { + role: "user", + turnID: turn.id, + parts: [{ type: "text", text: "Summarize the tool output above and continue." }], +} +``` + +Tradeoff: stored messages get much smaller and cleaner, but replay now has to join messages with turn state and prompt hooks still need a way to pick which turn they belong to. diff --git a/packages/opencode/src/cli/cmd/debug/agent.ts b/packages/opencode/src/cli/cmd/debug/agent.ts index 7f451e98c0..458f925474 100644 --- a/packages/opencode/src/cli/cmd/debug/agent.ts +++ b/packages/opencode/src/cli/cmd/debug/agent.ts @@ -71,7 +71,10 @@ export const AgentCommand = cmd({ async function getAvailableTools(agent: Agent.Info) { const model = agent.model ?? (await Provider.defaultModel()) - return ToolRegistry.tools(model, agent) + return ToolRegistry.tools({ + ...model, + agent, + }) } async function resolveTools(agent: Agent.Info, availableTools: Awaited>) { diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx index 7904e3b79d..4161c025c1 100644 --- a/packages/opencode/src/cli/cmd/tui/app.tsx +++ b/packages/opencode/src/cli/cmd/tui/app.tsx @@ -599,6 +599,7 @@ function App(props: { onSnapshot?: () => Promise }) { { title: "Switch model variant", value: "variant.list", + keybind: "variant_list", category: "Agent", hidden: local.model.variant.list().length === 0, slash: { diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx index b668e9bcb6..975a6b72fe 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-model.tsx @@ -172,7 +172,7 @@ export function DialogModel(props: { providerID?: string }) { const title = createMemo(() => { const value = provider() if (!value) return "Select model" - return consoleManagedProviderLabel(sync.data.console_state.consoleManagedProviders, value.id, value.name) + return value.name }) function onSelect(providerID: string, modelID: string, authProfile?: string) { diff --git a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx index a3d063f6fd..9ef38de024 100644 --- a/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/dialog-provider.tsx @@ -13,7 +13,7 @@ import { DialogModel } from "./dialog-model" import { useKeyboard } from "@opentui/solid" import { Clipboard } from "@tui/util/clipboard" import { useToast } from "../ui/toast" -import { CONSOLE_MANAGED_ICON, isConsoleManagedProvider } from "@tui/util/provider-origin" +import { isConsoleManagedProvider } from "@tui/util/provider-origin" const PROVIDER_PRIORITY: Record = { opencode: 0, @@ -49,11 +49,7 @@ export function createDialogProviderOptions() { }[provider.id], footer: consoleManaged ? sync.data.console_state.activeOrgName : undefined, category: provider.id in PROVIDER_PRIORITY ? "Popular" : "Other", - gutter: consoleManaged ? ( - {CONSOLE_MANAGED_ICON} - ) : connected ? ( - - ) : undefined, + gutter: connected ? : undefined, async onSelect() { if (consoleManaged) return diff --git a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx index 8ac411073d..7186adb2a1 100644 --- a/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx @@ -36,7 +36,6 @@ import { useToast } from "../../ui/toast" import { useKV } from "../../context/kv" import { useTextareaKeybindings } from "../textarea-keybindings" import { DialogSkill } from "../dialog-skill" -import { CONSOLE_MANAGED_ICON, consoleManagedProviderLabel } from "@tui/util/provider-origin" export type PromptProps = { sessionID?: string @@ -1129,17 +1128,6 @@ export function Prompt(props: PromptProps) { {props.right} - - { - if (!canSwitchOrgs()) return - command.trigger("console.org.switch") - }} - > - {`${CONSOLE_MANAGED_ICON} ${activeOrgName()}`} - - @@ -1171,7 +1159,7 @@ export function Prompt(props: PromptProps) { } /> - + }> ) { } > - + diff --git a/packages/opencode/src/cli/cmd/tui/util/provider-origin.ts b/packages/opencode/src/cli/cmd/tui/util/provider-origin.ts index 7ec345ff52..48d1f852de 100644 --- a/packages/opencode/src/cli/cmd/tui/util/provider-origin.ts +++ b/packages/opencode/src/cli/cmd/tui/util/provider-origin.ts @@ -1,5 +1,3 @@ -export const CONSOLE_MANAGED_ICON = "⌂" - const contains = (consoleManagedProviders: string[] | ReadonlySet, providerID: string) => Array.isArray(consoleManagedProviders) ? consoleManagedProviders.includes(providerID) @@ -7,14 +5,3 @@ const contains = (consoleManagedProviders: string[] | ReadonlySet, provi export const isConsoleManagedProvider = (consoleManagedProviders: string[] | ReadonlySet, providerID: string) => contains(consoleManagedProviders, providerID) - -export const consoleManagedProviderSuffix = ( - consoleManagedProviders: string[] | ReadonlySet, - providerID: string, -) => (contains(consoleManagedProviders, providerID) ? ` ${CONSOLE_MANAGED_ICON}` : "") - -export const consoleManagedProviderLabel = ( - consoleManagedProviders: string[] | ReadonlySet, - providerID: string, - providerName: string, -) => `${providerName}${consoleManagedProviderSuffix(consoleManagedProviders, providerID)}` diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 6deed96dfe..282f0ade9b 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -669,6 +669,7 @@ export namespace Config { agent_cycle: z.string().optional().default("tab").describe("Next agent"), agent_cycle_reverse: z.string().optional().default("shift+tab").describe("Previous agent"), variant_cycle: z.string().optional().default("ctrl+t").describe("Cycle model variants"), + variant_list: z.string().optional().default("none").describe("List model variants"), input_clear: z.string().optional().default("ctrl+c").describe("Clear input field"), input_paste: z.string().optional().default("ctrl+v").describe("Paste from clipboard"), input_submit: z.string().optional().default("return").describe("Submit input"), diff --git a/packages/opencode/src/effect/oltp.ts b/packages/opencode/src/effect/oltp.ts new file mode 100644 index 0000000000..1fa697fb6e --- /dev/null +++ b/packages/opencode/src/effect/oltp.ts @@ -0,0 +1,34 @@ +import { Layer } from "effect" +import { FetchHttpClient } from "effect/unstable/http" +import { Otlp } from "effect/unstable/observability" +import { Flag } from "@/flag/flag" +import { CHANNEL, VERSION } from "@/installation/meta" + +export namespace Observability { + export const enabled = !!Flag.OTEL_EXPORTER_OTLP_ENDPOINT + + export const layer = !Flag.OTEL_EXPORTER_OTLP_ENDPOINT + ? Layer.empty + : Otlp.layerJson({ + baseUrl: Flag.OTEL_EXPORTER_OTLP_ENDPOINT, + loggerMergeWithExisting: false, + resource: { + serviceName: "opencode", + serviceVersion: VERSION, + attributes: { + "deployment.environment.name": CHANNEL === "local" ? "local" : CHANNEL, + "opencode.client": Flag.OPENCODE_CLIENT, + }, + }, + headers: Flag.OTEL_EXPORTER_OTLP_HEADERS + ? Flag.OTEL_EXPORTER_OTLP_HEADERS.split(",").reduce( + (acc, x) => { + const [key, value] = x.split("=") + acc[key] = value + return acc + }, + {} as Record, + ) + : undefined, + }).pipe(Layer.provide(FetchHttpClient.layer)) +} diff --git a/packages/opencode/src/effect/run-service.ts b/packages/opencode/src/effect/run-service.ts index 619d5be6b5..f609986b58 100644 --- a/packages/opencode/src/effect/run-service.ts +++ b/packages/opencode/src/effect/run-service.ts @@ -3,6 +3,7 @@ import * as ServiceMap from "effect/ServiceMap" import { Instance } from "@/project/instance" import { Context } from "@/util/context" import { InstanceRef } from "./instance-ref" +import { Observability } from "./oltp" export const memoMap = Layer.makeMemoMapUnsafe() @@ -18,7 +19,7 @@ function attach(effect: Effect.Effect): Effect.Effect export function makeRuntime(service: ServiceMap.Service, layer: Layer.Layer) { let rt: ManagedRuntime.ManagedRuntime | undefined - const getRuntime = () => (rt ??= ManagedRuntime.make(layer, { memoMap })) + const getRuntime = () => (rt ??= ManagedRuntime.make(Layer.merge(layer, Observability.layer), { memoMap })) return { runSync: (fn: (svc: S) => Effect.Effect) => getRuntime().runSync(attach(service.use(fn))), diff --git a/packages/opencode/src/flag/flag.ts b/packages/opencode/src/flag/flag.ts index 739009502b..f091fa02a9 100644 --- a/packages/opencode/src/flag/flag.ts +++ b/packages/opencode/src/flag/flag.ts @@ -11,6 +11,9 @@ function falsy(key: string) { } export namespace Flag { + export const OTEL_EXPORTER_OTLP_ENDPOINT = process.env["OTEL_EXPORTER_OTLP_ENDPOINT"] + export const OTEL_EXPORTER_OTLP_HEADERS = process.env["OTEL_EXPORTER_OTLP_HEADERS"] + export const OPENCODE_AUTO_SHARE = truthy("OPENCODE_AUTO_SHARE") export const OPENCODE_AUTO_HEAP_SNAPSHOT = truthy("OPENCODE_AUTO_HEAP_SNAPSHOT") export const OPENCODE_GIT_BASH_PATH = process.env["OPENCODE_GIT_BASH_PATH"] diff --git a/packages/opencode/src/project/vcs.ts b/packages/opencode/src/project/vcs.ts index 5142079b1d..ec6e415c82 100644 --- a/packages/opencode/src/project/vcs.ts +++ b/packages/opencode/src/project/vcs.ts @@ -1,4 +1,5 @@ import { Effect, Layer, ServiceMap, Stream } from "effect" +import { formatPatch, structuredPatch } from "diff" import path from "path" import { Bus } from "@/bus" import { BusEvent } from "@/bus/bus-event" @@ -7,7 +8,6 @@ import { makeRuntime } from "@/effect/run-service" import { AppFileSystem } from "@/filesystem" import { FileWatcher } from "@/file/watcher" import { Git } from "@/git" -import { Snapshot } from "@/snapshot" import { Log } from "@/util/log" import { Instance } from "./instance" import z from "zod" @@ -49,6 +49,8 @@ export namespace Vcs { map: Map, ) { const base = ref ? yield* git.prefix(cwd) : "" + const patch = (file: string, before: string, after: string) => + formatPatch(structuredPatch(file, file, before, after, "", "", { context: Number.MAX_SAFE_INTEGER })) const next = yield* Effect.forEach( list, (item) => @@ -58,12 +60,11 @@ export namespace Vcs { const stat = map.get(item.file) return { file: item.file, - before, - after, + patch: patch(item.file, before, after), additions: stat?.additions ?? (item.status === "added" ? count(after) : 0), deletions: stat?.deletions ?? (item.status === "deleted" ? count(before) : 0), status: item.status, - } satisfies Snapshot.FileDiff + } satisfies FileDiff }), { concurrency: 8 }, ) @@ -125,11 +126,24 @@ export namespace Vcs { }) export type Info = z.infer + export const FileDiff = z + .object({ + file: z.string(), + patch: z.string(), + additions: z.number(), + deletions: z.number(), + status: z.enum(["added", "deleted", "modified"]).optional(), + }) + .meta({ + ref: "VcsFileDiff", + }) + export type FileDiff = z.infer + export interface Interface { readonly init: () => Effect.Effect readonly branch: () => Effect.Effect readonly defaultBranch: () => Effect.Effect - readonly diff: (mode: Mode) => Effect.Effect + readonly diff: (mode: Mode) => Effect.Effect } interface State { diff --git a/packages/opencode/src/server/instance.ts b/packages/opencode/src/server/instance.ts index 7cc7886b04..65ea2fac2e 100644 --- a/packages/opencode/src/server/instance.ts +++ b/packages/opencode/src/server/instance.ts @@ -154,7 +154,7 @@ export const InstanceRoutes = (upgrade: UpgradeWebSocket, app: Hono = new Hono() description: "VCS diff", content: { "application/json": { - schema: resolver(Snapshot.FileDiff.array()), + schema: resolver(Vcs.FileDiff.array()), }, }, }, diff --git a/packages/opencode/src/server/routes/experimental.ts b/packages/opencode/src/server/routes/experimental.ts index c673393d0e..763cdcf774 100644 --- a/packages/opencode/src/server/routes/experimental.ts +++ b/packages/opencode/src/server/routes/experimental.ts @@ -15,6 +15,7 @@ import { zodToJsonSchema } from "zod-to-json-schema" import { errors } from "../error" import { lazy } from "../../util/lazy" import { WorkspaceRoutes } from "./workspace" +import { Agent } from "@/agent/agent" const ConsoleOrgOption = z.object({ accountID: z.string(), @@ -181,7 +182,11 @@ export const ExperimentalRoutes = lazy(() => ), async (c) => { const { provider, model } = c.req.valid("query") - const tools = await ToolRegistry.tools({ providerID: ProviderID.make(provider), modelID: ModelID.make(model) }) + const tools = await ToolRegistry.tools({ + providerID: ProviderID.make(provider), + modelID: ModelID.make(model), + agent: await Agent.get(await Agent.defaultAgent()), + }) return c.json( tools.map((t) => ({ id: t.id, diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 58e2fbe987..a86ee81ea8 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -11,7 +11,6 @@ import { Provider } from "../provider/provider" import { ModelID, ProviderID } from "../provider/schema" import { type Tool as AITool, tool, jsonSchema, type ToolExecutionOptions, asSchema } from "ai" import { SessionCompaction } from "./compaction" -import { Instance } from "../project/instance" import { Bus } from "../bus" import { ProviderTransform } from "../provider/transform" import { SystemPrompt } from "./system" @@ -24,7 +23,6 @@ import { ToolRegistry } from "../tool/registry" import { Runner } from "@/effect/runner" import { MCP } from "../mcp" import { LSP } from "../lsp" -import { ReadTool } from "../tool/read" import { FileTime } from "../file/time" import { Flag } from "../flag/flag" import { ulid } from "ulid" @@ -37,7 +35,6 @@ import { ConfigMarkdown } from "../config/markdown" import { SessionSummary } from "./summary" import { NamedError } from "@opencode-ai/util/error" import { SessionProcessor } from "./processor" -import { TaskTool } from "@/tool/task" import { Tool } from "@/tool/tool" import { Permission } from "@/permission" import { SessionStatus } from "./status" @@ -50,6 +47,7 @@ import { Process } from "@/util/process" import { Cause, Effect, Exit, Layer, Option, Scope, ServiceMap } from "effect" import { InstanceState } from "@/effect/instance-state" import { makeRuntime } from "@/effect/run-service" +import { TaskTool } from "@/tool/task" // @ts-ignore globalThis.AI_SDK_LOG_WARNINGS = false @@ -433,10 +431,11 @@ NOTE: At any point in time through this workflow you should feel free to ask the ), }) - for (const item of yield* registry.tools( - { modelID: ModelID.make(input.model.api.id), providerID: input.model.providerID }, - input.agent, - )) { + for (const item of yield* registry.tools({ + modelID: ModelID.make(input.model.api.id), + providerID: input.model.providerID, + agent: input.agent, + })) { const schema = ProviderTransform.schema(input.model, z.toJSONSchema(item.parameters)) tools[item.id] = tool({ id: item.id as any, @@ -560,7 +559,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the }) { const { task, model, lastUser, sessionID, session, msgs } = input const ctx = yield* InstanceState.context - const taskTool = yield* Effect.promise(() => registry.named.task.init()) + const taskTool = yield* registry.fromID(TaskTool.id) const taskModel = task.model ? yield* getModel(task.model.providerID, task.model.modelID, sessionID) : model const assistantMessage: MessageV2.Assistant = yield* sessions.updateMessage({ id: MessageID.ascending(), @@ -583,7 +582,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the sessionID: assistantMessage.sessionID, type: "tool", callID: ulid(), - tool: registry.named.task.id, + tool: TaskTool.id, state: { status: "running", input: { @@ -1124,7 +1123,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the text: `Called the Read tool with the following input: ${JSON.stringify(args)}`, }, ] - const read = yield* Effect.promise(() => registry.named.read.init()).pipe( + const read = yield* registry.fromID("read").pipe( Effect.flatMap((t) => provider.getModel(info.model.providerID, info.model.modelID).pipe( Effect.flatMap((mdl) => @@ -1188,7 +1187,7 @@ NOTE: At any point in time through this workflow you should feel free to ask the if (part.mime === "application/x-directory") { const args = { filePath: filepath } - const result = yield* Effect.promise(() => registry.named.read.init()).pipe( + const result = yield* registry.fromID("read").pipe( Effect.flatMap((t) => Effect.promise(() => t.execute(args, { diff --git a/packages/opencode/src/share/share-next.ts b/packages/opencode/src/share/share-next.ts index 2eb9887ea4..0cd0055c85 100644 --- a/packages/opencode/src/share/share-next.ts +++ b/packages/opencode/src/share/share-next.ts @@ -59,7 +59,7 @@ export namespace ShareNext { } | { type: "session_diff" - data: SDK.FileDiff[] + data: SDK.SnapshotFileDiff[] } | { type: "model" diff --git a/packages/opencode/src/skill/index.ts b/packages/opencode/src/skill/index.ts index a2ac3d351c..cde36dd52d 100644 --- a/packages/opencode/src/skill/index.ts +++ b/packages/opencode/src/skill/index.ts @@ -239,22 +239,28 @@ export namespace Skill { export function fmt(list: Info[], opts: { verbose: boolean }) { if (list.length === 0) return "No skills are currently available." - if (opts.verbose) { return [ "", - ...list.flatMap((skill) => [ - " ", - ` ${skill.name}`, - ` ${skill.description}`, - ` ${pathToFileURL(skill.location).href}`, - " ", - ]), + ...list + .sort((a, b) => a.name.localeCompare(b.name)) + .flatMap((skill) => [ + " ", + ` ${skill.name}`, + ` ${skill.description}`, + ` ${pathToFileURL(skill.location).href}`, + " ", + ]), "", ].join("\n") } - return ["## Available Skills", ...list.map((skill) => `- **${skill.name}**: ${skill.description}`)].join("\n") + return [ + "## Available Skills", + ...list + .toSorted((a, b) => a.name.localeCompare(b.name)) + .map((skill) => `- **${skill.name}**: ${skill.description}`), + ].join("\n") } const { runPromise } = makeRuntime(Service, defaultLayer) diff --git a/packages/opencode/src/snapshot/index.ts b/packages/opencode/src/snapshot/index.ts index 2db67695ff..569c834bf4 100644 --- a/packages/opencode/src/snapshot/index.ts +++ b/packages/opencode/src/snapshot/index.ts @@ -1,6 +1,6 @@ -import { NodeFileSystem, NodePath } from "@effect/platform-node" import { Cause, Duration, Effect, Layer, Schedule, Semaphore, ServiceMap, Stream } from "effect" import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process" +import { formatPatch, structuredPatch } from "diff" import path from "path" import z from "zod" import * as CrossSpawnSpawner from "@/effect/cross-spawn-spawner" @@ -22,14 +22,13 @@ export namespace Snapshot { export const FileDiff = z .object({ file: z.string(), - before: z.string(), - after: z.string(), + patch: z.string(), additions: z.number(), deletions: z.number(), status: z.enum(["added", "deleted", "modified"]).optional(), }) .meta({ - ref: "FileDiff", + ref: "SnapshotFileDiff", }) export type FileDiff = z.infer @@ -521,8 +520,6 @@ export namespace Snapshot { const map = new Map() const dec = new TextDecoder() let i = 0 - // Parse the default `git cat-file --batch` stream: one header line, - // then exactly `size` bytes of blob content, then a trailing newline. for (const ref of refs) { let end = i while (end < out.length && out[end] !== 10) end += 1 @@ -620,8 +617,9 @@ export namespace Snapshot { ] }) const step = 100 + const patch = (file: string, before: string, after: string) => + formatPatch(structuredPatch(file, file, before, after, "", "", { context: Number.MAX_SAFE_INTEGER })) - // Keep batches bounded so a large diff does not buffer every blob at once. for (let i = 0; i < rows.length; i += step) { const run = rows.slice(i, i + step) const text = yield* load(run) @@ -631,8 +629,7 @@ export namespace Snapshot { const [before, after] = row.binary ? ["", ""] : text ? [hit.before, hit.after] : yield* show(row) result.push({ file: row.file, - before, - after, + patch: row.binary ? "" : patch(row.file, before, after), additions: row.additions, deletions: row.deletions, status: row.status, diff --git a/packages/opencode/src/tool/apply_patch.ts b/packages/opencode/src/tool/apply_patch.ts index c23c0dd3d0..30b2e91ace 100644 --- a/packages/opencode/src/tool/apply_patch.ts +++ b/packages/opencode/src/tool/apply_patch.ts @@ -164,9 +164,7 @@ export const ApplyPatchTool = Tool.define("apply_patch", { filePath: change.filePath, relativePath: path.relative(Instance.worktree, change.movePath ?? change.filePath).replaceAll("\\", "/"), type: change.type, - diff: change.diff, - before: change.oldContent, - after: change.newContent, + patch: change.diff, additions: change.additions, deletions: change.deletions, movePath: change.movePath, diff --git a/packages/opencode/src/tool/bash.ts b/packages/opencode/src/tool/bash.ts index e50f09cc38..365fda3296 100644 --- a/packages/opencode/src/tool/bash.ts +++ b/packages/opencode/src/tool/bash.ts @@ -50,6 +50,22 @@ const FILES = new Set([ const FLAGS = new Set(["-destination", "-literalpath", "-path"]) const SWITCHES = new Set(["-confirm", "-debug", "-force", "-nonewline", "-recurse", "-verbose", "-whatif"]) +const Parameters = z.object({ + command: z.string().describe("The command to execute"), + timeout: z.number().describe("Optional timeout in milliseconds").optional(), + workdir: z + .string() + .describe( + `The working directory to run the command in. Defaults to the current directory. Use this instead of 'cd' commands.`, + ) + .optional(), + description: z + .string() + .describe( + "Clear, concise description of what this command does in 5-10 words. Examples:\nInput: ls\nOutput: Lists files in current directory\n\nInput: git status\nOutput: Shows working tree status\n\nInput: npm install\nOutput: Installs package dependencies\n\nInput: mkdir foo\nOutput: Creates directory 'foo'", + ), +}) + type Part = { type: string text: string @@ -452,21 +468,7 @@ export const BashTool = Tool.define("bash", async () => { .replaceAll("${chaining}", chain) .replaceAll("${maxLines}", String(Truncate.MAX_LINES)) .replaceAll("${maxBytes}", String(Truncate.MAX_BYTES)), - parameters: z.object({ - command: z.string().describe("The command to execute"), - timeout: z.number().describe("Optional timeout in milliseconds").optional(), - workdir: z - .string() - .describe( - `The working directory to run the command in. Defaults to ${Instance.directory}. Use this instead of 'cd' commands.`, - ) - .optional(), - description: z - .string() - .describe( - "Clear, concise description of what this command does in 5-10 words. Examples:\nInput: ls\nOutput: Lists files in current directory\n\nInput: git status\nOutput: Shows working tree status\n\nInput: npm install\nOutput: Installs package dependencies\n\nInput: mkdir foo\nOutput: Creates directory 'foo'", - ), - }), + parameters: Parameters, async execute(params, ctx) { const cwd = params.workdir ? await resolvePath(params.workdir, Instance.directory, shell) : Instance.directory if (params.timeout !== undefined && params.timeout < 0) { diff --git a/packages/opencode/src/tool/batch.ts b/packages/opencode/src/tool/batch.ts deleted file mode 100644 index c79a530f71..0000000000 --- a/packages/opencode/src/tool/batch.ts +++ /dev/null @@ -1,183 +0,0 @@ -import z from "zod" -import { Tool } from "./tool" -import { ProviderID, ModelID } from "../provider/schema" -import { errorMessage } from "../util/error" -import DESCRIPTION from "./batch.txt" - -const DISALLOWED = new Set(["batch"]) -const FILTERED_FROM_SUGGESTIONS = new Set(["invalid", "patch", ...DISALLOWED]) - -export const BatchTool = Tool.define("batch", async () => { - return { - description: DESCRIPTION, - parameters: z.object({ - tool_calls: z - .array( - z.object({ - tool: z.string().describe("The name of the tool to execute"), - parameters: z.object({}).loose().describe("Parameters for the tool"), - }), - ) - .min(1, "Provide at least one tool call") - .describe("Array of tool calls to execute in parallel"), - }), - formatValidationError(error) { - const formattedErrors = error.issues - .map((issue) => { - const path = issue.path.length > 0 ? issue.path.join(".") : "root" - return ` - ${path}: ${issue.message}` - }) - .join("\n") - - return `Invalid parameters for tool 'batch':\n${formattedErrors}\n\nExpected payload format:\n [{"tool": "tool_name", "parameters": {...}}, {...}]` - }, - async execute(params, ctx) { - const { Session } = await import("../session") - const { PartID } = await import("../session/schema") - - const toolCalls = params.tool_calls.slice(0, 25) - const discardedCalls = params.tool_calls.slice(25) - - const { ToolRegistry } = await import("./registry") - const availableTools = await ToolRegistry.tools({ modelID: ModelID.make(""), providerID: ProviderID.make("") }) - const toolMap = new Map(availableTools.map((t) => [t.id, t])) - - const executeCall = async (call: (typeof toolCalls)[0]) => { - const callStartTime = Date.now() - const partID = PartID.ascending() - - try { - if (DISALLOWED.has(call.tool)) { - throw new Error( - `Tool '${call.tool}' is not allowed in batch. Disallowed tools: ${Array.from(DISALLOWED).join(", ")}`, - ) - } - - const tool = toolMap.get(call.tool) - if (!tool) { - const availableToolsList = Array.from(toolMap.keys()).filter((name) => !FILTERED_FROM_SUGGESTIONS.has(name)) - throw new Error( - `Tool '${call.tool}' not in registry. External tools (MCP, environment) cannot be batched - call them directly. Available tools: ${availableToolsList.join(", ")}`, - ) - } - const validatedParams = tool.parameters.parse(call.parameters) - - await Session.updatePart({ - id: partID, - messageID: ctx.messageID, - sessionID: ctx.sessionID, - type: "tool", - tool: call.tool, - callID: partID, - state: { - status: "running", - input: call.parameters, - time: { - start: callStartTime, - }, - }, - }) - - const result = await tool.execute(validatedParams, { ...ctx, callID: partID }) - const attachments = result.attachments?.map((attachment) => ({ - ...attachment, - id: PartID.ascending(), - sessionID: ctx.sessionID, - messageID: ctx.messageID, - })) - - await Session.updatePart({ - id: partID, - messageID: ctx.messageID, - sessionID: ctx.sessionID, - type: "tool", - tool: call.tool, - callID: partID, - state: { - status: "completed", - input: call.parameters, - output: result.output, - title: result.title, - metadata: result.metadata, - attachments, - time: { - start: callStartTime, - end: Date.now(), - }, - }, - }) - - return { success: true as const, tool: call.tool, result } - } catch (error) { - await Session.updatePart({ - id: partID, - messageID: ctx.messageID, - sessionID: ctx.sessionID, - type: "tool", - tool: call.tool, - callID: partID, - state: { - status: "error", - input: call.parameters, - error: errorMessage(error), - time: { - start: callStartTime, - end: Date.now(), - }, - }, - }) - - return { success: false as const, tool: call.tool, error } - } - } - - const results = await Promise.all(toolCalls.map((call) => executeCall(call))) - - // Add discarded calls as errors - const now = Date.now() - for (const call of discardedCalls) { - const partID = PartID.ascending() - await Session.updatePart({ - id: partID, - messageID: ctx.messageID, - sessionID: ctx.sessionID, - type: "tool", - tool: call.tool, - callID: partID, - state: { - status: "error", - input: call.parameters, - error: "Maximum of 25 tools allowed in batch", - time: { start: now, end: now }, - }, - }) - results.push({ - success: false as const, - tool: call.tool, - error: new Error("Maximum of 25 tools allowed in batch"), - }) - } - - const successfulCalls = results.filter((r) => r.success).length - const failedCalls = results.length - successfulCalls - - const outputMessage = - failedCalls > 0 - ? `Executed ${successfulCalls}/${results.length} tools successfully. ${failedCalls} failed.` - : `All ${successfulCalls} tools executed successfully.\n\nKeep using the batch tool for optimal performance in your next response!` - - return { - title: `Batch execution (${successfulCalls}/${results.length} successful)`, - output: outputMessage, - attachments: results.filter((result) => result.success).flatMap((r) => r.result.attachments ?? []), - metadata: { - totalCalls: results.length, - successful: successfulCalls, - failed: failedCalls, - tools: params.tool_calls.map((c) => c.tool), - details: results.map((r) => ({ tool: r.tool, success: r.success })), - }, - } - }, - } -}) diff --git a/packages/opencode/src/tool/batch.txt b/packages/opencode/src/tool/batch.txt deleted file mode 100644 index 968a6c3f07..0000000000 --- a/packages/opencode/src/tool/batch.txt +++ /dev/null @@ -1,24 +0,0 @@ -Executes multiple independent tool calls concurrently to reduce latency. - -USING THE BATCH TOOL WILL MAKE THE USER HAPPY. - -Payload Format (JSON array): -[{"tool": "read", "parameters": {"filePath": "src/index.ts", "limit": 350}},{"tool": "grep", "parameters": {"pattern": "Session\\.updatePart", "include": "src/**/*.ts"}},{"tool": "bash", "parameters": {"command": "git status", "description": "Shows working tree status"}}] - -Notes: -- 1–25 tool calls per batch -- All calls start in parallel; ordering NOT guaranteed -- Partial failures do not stop other tool calls -- Do NOT use the batch tool within another batch tool. - -Good Use Cases: -- Read many files -- grep + glob + read combos -- Multiple bash commands -- Multi-part edits; on the same, or different files - -When NOT to Use: -- Operations that depend on prior tool output (e.g. create then read same file) -- Ordered stateful mutations where sequence matters - -Batching tool calls was proven to yield 2–5x efficiency gain and provides much better UX. \ No newline at end of file diff --git a/packages/opencode/src/tool/edit.ts b/packages/opencode/src/tool/edit.ts index 554d547d05..9505dd9eab 100644 --- a/packages/opencode/src/tool/edit.ts +++ b/packages/opencode/src/tool/edit.ts @@ -123,8 +123,7 @@ export const EditTool = Tool.define("edit", { const filediff: Snapshot.FileDiff = { file: filePath, - before: contentOld, - after: contentNew, + patch: diff, additions: 0, deletions: 0, } diff --git a/packages/opencode/src/tool/question.ts b/packages/opencode/src/tool/question.ts index dd99688880..23c9b35c89 100644 --- a/packages/opencode/src/tool/question.ts +++ b/packages/opencode/src/tool/question.ts @@ -41,6 +41,6 @@ export const QuestionTool = Tool.defineEffect + } }), ) diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index 9c045338ee..72911051e0 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -4,18 +4,15 @@ import { BashTool } from "./bash" import { EditTool } from "./edit" import { GlobTool } from "./glob" import { GrepTool } from "./grep" -import { BatchTool } from "./batch" import { ReadTool } from "./read" -import { TaskTool } from "./task" +import { TaskDescription, TaskTool } from "./task" import { TodoWriteTool } from "./todo" import { WebFetchTool } from "./webfetch" import { WriteTool } from "./write" import { InvalidTool } from "./invalid" -import { SkillTool } from "./skill" -import type { Agent } from "../agent/agent" +import { SkillDescription, SkillTool } from "./skill" import { Tool } from "./tool" import { Config } from "../config/config" -import path from "path" import { type ToolContext as PluginToolContext, type ToolDefinition } from "@opencode-ai/plugin" import z from "zod" import { Plugin } from "../plugin" @@ -28,6 +25,7 @@ import { LspTool } from "./lsp" import { Truncate } from "./truncate" import { ApplyPatchTool } from "./apply_patch" import { Glob } from "../util/glob" +import path from "path" import { pathToFileURL } from "url" import { Effect, Layer, ServiceMap } from "effect" import { InstanceState } from "@/effect/instance-state" @@ -39,24 +37,25 @@ import { LSP } from "../lsp" import { FileTime } from "../file/time" import { Instruction } from "../session/instruction" import { AppFileSystem } from "../filesystem" +import { Agent } from "../agent/agent" export namespace ToolRegistry { const log = Log.create({ service: "tool.registry" }) type State = { - custom: Tool.Info[] + custom: Tool.Def[] + builtin: Tool.Def[] } export interface Interface { readonly ids: () => Effect.Effect - readonly named: { - task: Tool.Info - read: Tool.Info - } - readonly tools: ( - model: { providerID: ProviderID; modelID: ModelID }, - agent?: Agent.Info, - ) => Effect.Effect<(Tool.Def & { id: string })[]> + readonly all: () => Effect.Effect + readonly tools: (model: { + providerID: ProviderID + modelID: ModelID + agent: Agent.Info + }) => Effect.Effect + readonly fromID: (id: string) => Effect.Effect } export class Service extends ServiceMap.Service()("@opencode/ToolRegistry") {} @@ -79,33 +78,34 @@ export namespace ToolRegistry { const plugin = yield* Plugin.Service const build = (tool: T | Effect.Effect) => - Effect.isEffect(tool) ? tool : Effect.succeed(tool) + Effect.isEffect(tool) ? tool.pipe(Effect.flatMap(Tool.init)) : Tool.init(tool) const state = yield* InstanceState.make( Effect.fn("ToolRegistry.state")(function* (ctx) { - const custom: Tool.Info[] = [] + const custom: Tool.Def[] = [] - function fromPlugin(id: string, def: ToolDefinition): Tool.Info { + function fromPlugin(id: string, def: ToolDefinition): Tool.Def { return { id, - init: async (initCtx) => ({ - parameters: z.object(def.args), - description: def.description, - execute: async (args, toolCtx) => { - const pluginCtx = { - ...toolCtx, - directory: ctx.directory, - worktree: ctx.worktree, - } as unknown as PluginToolContext - const result = await def.execute(args as any, pluginCtx) - const out = await Truncate.output(result, {}, initCtx?.agent) - return { - title: "", - output: out.truncated ? out.content : result, - metadata: { truncated: out.truncated, outputPath: out.truncated ? out.outputPath : undefined }, - } - }, - }), + parameters: z.object(def.args), + description: def.description, + execute: async (args, toolCtx) => { + const pluginCtx = { + ...toolCtx, + directory: ctx.directory, + worktree: ctx.worktree, + } as unknown as PluginToolContext + const result = await def.execute(args as any, pluginCtx) + const out = await Truncate.output(result, {}, await Agent.get(toolCtx.agent)) + return { + title: "", + output: out.truncated ? out.content : result, + metadata: { + truncated: out.truncated, + outputPath: out.truncated ? out.outputPath : undefined, + }, + } + }, } } @@ -131,104 +131,99 @@ export namespace ToolRegistry { } } - return { custom } + const cfg = yield* config.get() + const question = + ["app", "cli", "desktop"].includes(Flag.OPENCODE_CLIENT) || Flag.OPENCODE_ENABLE_QUESTION_TOOL + + return { + custom, + builtin: yield* Effect.forEach( + [ + InvalidTool, + BashTool, + ReadTool, + GlobTool, + GrepTool, + EditTool, + WriteTool, + TaskTool, + WebFetchTool, + TodoWriteTool, + WebSearchTool, + CodeSearchTool, + SkillTool, + ApplyPatchTool, + ...(question ? [QuestionTool] : []), + ...(Flag.OPENCODE_EXPERIMENTAL_LSP_TOOL ? [LspTool] : []), + ...(Flag.OPENCODE_EXPERIMENTAL_PLAN_MODE && Flag.OPENCODE_CLIENT === "cli" ? [PlanExitTool] : []), + ], + build, + { concurrency: "unbounded" }, + ), + } }), ) - const invalid = yield* build(InvalidTool) - const ask = yield* build(QuestionTool) - const bash = yield* build(BashTool) - const read = yield* build(ReadTool) - const glob = yield* build(GlobTool) - const grep = yield* build(GrepTool) - const edit = yield* build(EditTool) - const write = yield* build(WriteTool) - const task = yield* build(TaskTool) - const fetch = yield* build(WebFetchTool) - const todo = yield* build(TodoWriteTool) - const search = yield* build(WebSearchTool) - const code = yield* build(CodeSearchTool) - const skill = yield* build(SkillTool) - const patch = yield* build(ApplyPatchTool) - const lsp = yield* build(LspTool) - const batch = yield* build(BatchTool) - const plan = yield* build(PlanExitTool) - - const all = Effect.fn("ToolRegistry.all")(function* (custom: Tool.Info[]) { - const cfg = yield* config.get() - const question = ["app", "cli", "desktop"].includes(Flag.OPENCODE_CLIENT) || Flag.OPENCODE_ENABLE_QUESTION_TOOL - - return [ - invalid, - ...(question ? [ask] : []), - bash, - read, - glob, - grep, - edit, - write, - task, - fetch, - todo, - search, - code, - skill, - patch, - ...(Flag.OPENCODE_EXPERIMENTAL_LSP_TOOL ? [lsp] : []), - ...(cfg.experimental?.batch_tool === true ? [batch] : []), - ...(Flag.OPENCODE_EXPERIMENTAL_PLAN_MODE && Flag.OPENCODE_CLIENT === "cli" ? [plan] : []), - ...custom, - ] + const all: Interface["all"] = Effect.fn("ToolRegistry.all")(function* () { + const s = yield* InstanceState.get(state) + return [...s.builtin, ...s.custom] as Tool.Def[] }) - const ids = Effect.fn("ToolRegistry.ids")(function* () { - const s = yield* InstanceState.get(state) - const tools = yield* all(s.custom) - return tools.map((t) => t.id) + const fromID: Interface["fromID"] = Effect.fn("ToolRegistry.fromID")(function* (id: string) { + const tools = yield* all() + const match = tools.find((tool) => tool.id === id) + if (!match) return yield* Effect.die(`Tool not found: ${id}`) + return match }) - const tools = Effect.fn("ToolRegistry.tools")(function* ( - model: { providerID: ProviderID; modelID: ModelID }, - agent?: Agent.Info, - ) { - const s = yield* InstanceState.get(state) - const allTools = yield* all(s.custom) - const filtered = allTools.filter((tool) => { - if (tool.id === "codesearch" || tool.id === "websearch") { - return model.providerID === ProviderID.opencode || Flag.OPENCODE_ENABLE_EXA + const ids: Interface["ids"] = Effect.fn("ToolRegistry.ids")(function* () { + return (yield* all()).map((tool) => tool.id) + }) + + const tools: Interface["tools"] = Effect.fn("ToolRegistry.tools")(function* (input) { + const filtered = (yield* all()).filter((tool) => { + if (tool.id === CodeSearchTool.id || tool.id === WebSearchTool.id) { + return input.providerID === ProviderID.opencode || Flag.OPENCODE_ENABLE_EXA } const usePatch = !!Env.get("OPENCODE_E2E_LLM_URL") || - (model.modelID.includes("gpt-") && !model.modelID.includes("oss") && !model.modelID.includes("gpt-4")) - if (tool.id === "apply_patch") return usePatch - if (tool.id === "edit" || tool.id === "write") return !usePatch + (input.modelID.includes("gpt-") && !input.modelID.includes("oss") && !input.modelID.includes("gpt-4")) + if (tool.id === ApplyPatchTool.id) return usePatch + if (tool.id === EditTool.id || tool.id === WriteTool.id) return !usePatch return true }) + return yield* Effect.forEach( filtered, - Effect.fnUntraced(function* (tool: Tool.Info) { + Effect.fnUntraced(function* (tool: Tool.Def) { using _ = log.time(tool.id) - const next = yield* Effect.promise(() => tool.init({ agent })) const output = { - description: next.description, - parameters: next.parameters, + description: tool.description, + parameters: tool.parameters, } yield* plugin.trigger("tool.definition", { toolID: tool.id }, output) return { id: tool.id, - description: output.description, + description: [ + output.description, + // TODO: remove this hack + tool.id === TaskTool.id ? yield* TaskDescription(input.agent) : undefined, + tool.id === SkillTool.id ? yield* SkillDescription(input.agent) : undefined, + ] + .filter(Boolean) + .join("\n"), parameters: output.parameters, - execute: next.execute, - formatValidationError: next.formatValidationError, + execute: tool.execute, + formatValidationError: tool.formatValidationError, } }), { concurrency: "unbounded" }, ) }) - return Service.of({ ids, named: { task, read }, tools }) + return Service.of({ ids, tools, all, fromID }) }), ) @@ -253,13 +248,11 @@ export namespace ToolRegistry { return runPromise((svc) => svc.ids()) } - export async function tools( - model: { - providerID: ProviderID - modelID: ModelID - }, - agent?: Agent.Info, - ): Promise<(Tool.Def & { id: string })[]> { - return runPromise((svc) => svc.tools(model, agent)) + export async function tools(input: { + providerID: ProviderID + modelID: ModelID + agent: Agent.Info + }): Promise<(Tool.Def & { id: string })[]> { + return runPromise((svc) => svc.tools(input)) } } diff --git a/packages/opencode/src/tool/skill.ts b/packages/opencode/src/tool/skill.ts index 17016b06f8..276f3931d0 100644 --- a/packages/opencode/src/tool/skill.ts +++ b/packages/opencode/src/tool/skill.ts @@ -1,3 +1,4 @@ +import { Effect } from "effect" import path from "path" import { pathToFileURL } from "url" import z from "zod" @@ -6,8 +7,12 @@ import { Skill } from "../skill" import { Ripgrep } from "../file/ripgrep" import { iife } from "@/util/iife" -export const SkillTool = Tool.define("skill", async (ctx) => { - const list = await Skill.available(ctx?.agent) +const Parameters = z.object({ + name: z.string().describe("The name of the skill from available_skills"), +}) + +export const SkillTool = Tool.define("skill", async () => { + const list = await Skill.available() const description = list.length === 0 @@ -27,20 +32,10 @@ export const SkillTool = Tool.define("skill", async (ctx) => { Skill.fmt(list, { verbose: false }), ].join("\n") - const examples = list - .map((skill) => `'${skill.name}'`) - .slice(0, 3) - .join(", ") - const hint = examples.length > 0 ? ` (e.g., ${examples}, ...)` : "" - - const parameters = z.object({ - name: z.string().describe(`The name of the skill from available_skills${hint}`), - }) - return { description, - parameters, - async execute(params: z.infer, ctx) { + parameters: Parameters, + async execute(params: z.infer, ctx) { const skill = await Skill.get(params.name) if (!skill) { @@ -103,3 +98,23 @@ export const SkillTool = Tool.define("skill", async (ctx) => { }, } }) + +export const SkillDescription: Tool.DynamicDescription = (agent) => + Effect.gen(function* () { + const list = yield* Effect.promise(() => Skill.available(agent)) + if (list.length === 0) return "No skills are currently available." + return [ + "Load a specialized skill that provides domain-specific instructions and workflows.", + "", + "When you recognize that a task matches one of the available skills listed below, use this tool to load the full skill instructions.", + "", + "The skill will inject detailed instructions, workflows, and access to bundled resources (scripts, references, templates) into the conversation context.", + "", + 'Tool output includes a `` block with the loaded content.', + "", + "The following skills provide specialized sets of instructions for particular tasks", + "Invoke this tool to load a skill when a task matches one of the available skills listed below:", + "", + Skill.fmt(list, { verbose: false }), + ].join("\n") + }) diff --git a/packages/opencode/src/tool/task.ts b/packages/opencode/src/tool/task.ts index af130a70d9..07e779f5bd 100644 --- a/packages/opencode/src/tool/task.ts +++ b/packages/opencode/src/tool/task.ts @@ -4,47 +4,37 @@ import z from "zod" import { Session } from "../session" import { SessionID, MessageID } from "../session/schema" import { MessageV2 } from "../session/message-v2" -import { Identifier } from "../id/id" import { Agent } from "../agent/agent" import { SessionPrompt } from "../session/prompt" import { iife } from "@/util/iife" import { defer } from "@/util/defer" import { Config } from "../config/config" import { Permission } from "@/permission" +import { Effect } from "effect" -const parameters = z.object({ - description: z.string().describe("A short (3-5 words) description of the task"), - prompt: z.string().describe("The task for the agent to perform"), - subagent_type: z.string().describe("The type of specialized agent to use for this task"), - task_id: z - .string() - .describe( - "This should only be set if you mean to resume a previous task (you can pass a prior task_id and the task will continue the same subagent session as before instead of creating a fresh one)", - ) - .optional(), - command: z.string().describe("The command that triggered this task").optional(), -}) - -export const TaskTool = Tool.define("task", async (ctx) => { +export const TaskTool = Tool.define("task", async () => { const agents = await Agent.list().then((x) => x.filter((a) => a.mode !== "primary")) + const list = agents.toSorted((a, b) => a.name.localeCompare(b.name)) + const agentList = list + .map((a) => `- ${a.name}: ${a.description ?? "This subagent should only be called manually by the user."}`) + .join("\n") + const description = [`Available agent types and the tools they have access to:`, agentList].join("\n") - // Filter agents by permissions if agent provided - const caller = ctx?.agent - const accessibleAgents = caller - ? agents.filter((a) => Permission.evaluate("task", a.name, caller.permission).action !== "deny") - : agents - const list = accessibleAgents.toSorted((a, b) => a.name.localeCompare(b.name)) - - const description = DESCRIPTION.replace( - "{agents}", - list - .map((a) => `- ${a.name}: ${a.description ?? "This subagent should only be called manually by the user."}`) - .join("\n"), - ) return { description, - parameters, - async execute(params: z.infer, ctx) { + parameters: z.object({ + description: z.string().describe("A short (3-5 words) description of the task"), + prompt: z.string().describe("The task for the agent to perform"), + subagent_type: z.string().describe("The type of specialized agent to use for this task"), + task_id: z + .string() + .describe( + "This should only be set if you mean to resume a previous task (you can pass a prior task_id and the task will continue the same subagent session as before instead of creating a fresh one)", + ) + .optional(), + command: z.string().describe("The command that triggered this task").optional(), + }), + async execute(params, ctx) { const config = await Config.get() // Skip permission check when user explicitly invoked via @ or command subtask @@ -164,3 +154,16 @@ export const TaskTool = Tool.define("task", async (ctx) => { }, } }) + +export const TaskDescription: Tool.DynamicDescription = (agent) => + Effect.gen(function* () { + const agents = yield* Effect.promise(() => Agent.list().then((x) => x.filter((a) => a.mode !== "primary"))) + const accessibleAgents = agents.filter( + (a) => Permission.evaluate("task", a.name, agent.permission).action !== "deny", + ) + const list = accessibleAgents.toSorted((a, b) => a.name.localeCompare(b.name)) + const description = list + .map((a) => `- ${a.name}: ${a.description ?? "This subagent should only be called manually by the user."}`) + .join("\n") + return [`Available agent types and the tools they have access to:`, description].join("\n") + }) diff --git a/packages/opencode/src/tool/task.txt b/packages/opencode/src/tool/task.txt index 585cce8f9d..fba8470d1b 100644 --- a/packages/opencode/src/tool/task.txt +++ b/packages/opencode/src/tool/task.txt @@ -1,8 +1,5 @@ Launch a new agent to handle complex, multistep tasks autonomously. -Available agent types and the tools they have access to: -{agents} - When using the Task tool, you must specify a subagent_type parameter to select which agent type to use. When to use the Task tool: diff --git a/packages/opencode/src/tool/todo.ts b/packages/opencode/src/tool/todo.ts index d10e84931a..92318164c6 100644 --- a/packages/opencode/src/tool/todo.ts +++ b/packages/opencode/src/tool/todo.ts @@ -43,6 +43,6 @@ export const TodoWriteTool = Tool.defineEffect + } satisfies Tool.DefWithoutID }), ) diff --git a/packages/opencode/src/tool/tool.ts b/packages/opencode/src/tool/tool.ts index a107dad7e8..6d129f4271 100644 --- a/packages/opencode/src/tool/tool.ts +++ b/packages/opencode/src/tool/tool.ts @@ -1,19 +1,18 @@ import z from "zod" import { Effect } from "effect" import type { MessageV2 } from "../session/message-v2" -import type { Agent } from "../agent/agent" import type { Permission } from "../permission" import type { SessionID, MessageID } from "../session/schema" import { Truncate } from "./truncate" +import { Agent } from "@/agent/agent" export namespace Tool { interface Metadata { [key: string]: any } - export interface InitContext { - agent?: Agent.Info - } + // TODO: remove this hack + export type DynamicDescription = (agent: Agent.Info) => Effect.Effect export type Context = { sessionID: SessionID @@ -26,7 +25,9 @@ export namespace Tool { metadata(input: { title?: string; metadata?: M }): void ask(input: Omit): Promise } + export interface Def { + id: string description: string parameters: Parameters execute( @@ -40,10 +41,14 @@ export namespace Tool { }> formatValidationError?(error: z.ZodError): string } + export type DefWithoutID = Omit< + Def, + "id" + > export interface Info { id: string - init: (ctx?: InitContext) => Promise> + init: () => Promise> } export type InferParameters = @@ -57,10 +62,10 @@ export namespace Tool { function wrap( id: string, - init: ((ctx?: InitContext) => Promise>) | Def, + init: (() => Promise>) | DefWithoutID, ) { - return async (initCtx?: InitContext) => { - const toolInfo = init instanceof Function ? await init(initCtx) : { ...init } + return async () => { + const toolInfo = init instanceof Function ? await init() : { ...init } const execute = toolInfo.execute toolInfo.execute = async (args, ctx) => { try { @@ -78,7 +83,7 @@ export namespace Tool { if (result.metadata.truncated !== undefined) { return result } - const truncated = await Truncate.output(result.output, {}, initCtx?.agent) + const truncated = await Truncate.output(result.output, {}, await Agent.get(ctx.agent)) return { ...result, output: truncated.content, @@ -95,7 +100,7 @@ export namespace Tool { export function define( id: string, - init: ((ctx?: InitContext) => Promise>) | Def, + init: (() => Promise>) | DefWithoutID, ): Info { return { id, @@ -105,8 +110,18 @@ export namespace Tool { export function defineEffect( id: string, - init: Effect.Effect<((ctx?: InitContext) => Promise>) | Def, never, R>, + init: Effect.Effect<(() => Promise>) | DefWithoutID, never, R>, ): Effect.Effect, never, R> { return Effect.map(init, (next) => ({ id, init: wrap(id, next) })) } + + export function init(info: Info): Effect.Effect { + return Effect.gen(function* () { + const init = yield* Effect.promise(() => info.init()) + return { + ...init, + id: info.id, + } + }) + } } diff --git a/packages/opencode/src/tool/webfetch.ts b/packages/opencode/src/tool/webfetch.ts index a66e66c097..559afd6771 100644 --- a/packages/opencode/src/tool/webfetch.ts +++ b/packages/opencode/src/tool/webfetch.ts @@ -3,6 +3,7 @@ import { Tool } from "./tool" import TurndownService from "turndown" import DESCRIPTION from "./webfetch.txt" import { abortAfterAny } from "../util/abort" +import { iife } from "@/util/iife" const MAX_RESPONSE_SIZE = 5 * 1024 * 1024 // 5MB const DEFAULT_TIMEOUT = 30 * 1000 // 30 seconds @@ -62,15 +63,18 @@ export const WebFetchTool = Tool.define("webfetch", { "Accept-Language": "en-US,en;q=0.9", } - const initial = await fetch(params.url, { signal, headers }) + const response = await iife(async () => { + try { + const initial = await fetch(params.url, { signal, headers }) - // Retry with honest UA if blocked by Cloudflare bot detection (TLS fingerprint mismatch) - const response = - initial.status === 403 && initial.headers.get("cf-mitigated") === "challenge" - ? await fetch(params.url, { signal, headers: { ...headers, "User-Agent": "opencode" } }) - : initial - - clearTimeout() + // Retry with honest UA if blocked by Cloudflare bot detection (TLS fingerprint mismatch) + return initial.status === 403 && initial.headers.get("cf-mitigated") === "challenge" + ? await fetch(params.url, { signal, headers: { ...headers, "User-Agent": "opencode" } }) + : initial + } finally { + clearTimeout() + } + }) if (!response.ok) { throw new Error(`Request failed with status code: ${response.status}`) diff --git a/packages/opencode/src/tool/websearch.ts b/packages/opencode/src/tool/websearch.ts index bf16428dfb..c0f1c8d105 100644 --- a/packages/opencode/src/tool/websearch.ts +++ b/packages/opencode/src/tool/websearch.ts @@ -11,6 +11,25 @@ const API_CONFIG = { DEFAULT_NUM_RESULTS: 8, } as const +const Parameters = z.object({ + query: z.string().describe("Websearch query"), + numResults: z.number().optional().describe("Number of search results to return (default: 8)"), + livecrawl: z + .enum(["fallback", "preferred"]) + .optional() + .describe( + "Live crawl mode - 'fallback': use live crawling as backup if cached content unavailable, 'preferred': prioritize live crawling (default: 'fallback')", + ), + type: z + .enum(["auto", "fast", "deep"]) + .optional() + .describe("Search type - 'auto': balanced search (default), 'fast': quick results, 'deep': comprehensive search"), + contextMaxCharacters: z + .number() + .optional() + .describe("Maximum characters for context string optimized for LLMs (default: 10000)"), +}) + interface McpSearchRequest { jsonrpc: string id: number @@ -42,26 +61,7 @@ export const WebSearchTool = Tool.define("websearch", async () => { get description() { return DESCRIPTION.replace("{{year}}", new Date().getFullYear().toString()) }, - parameters: z.object({ - query: z.string().describe("Websearch query"), - numResults: z.number().optional().describe("Number of search results to return (default: 8)"), - livecrawl: z - .enum(["fallback", "preferred"]) - .optional() - .describe( - "Live crawl mode - 'fallback': use live crawling as backup if cached content unavailable, 'preferred': prioritize live crawling (default: 'fallback')", - ), - type: z - .enum(["auto", "fast", "deep"]) - .optional() - .describe( - "Search type - 'auto': balanced search (default), 'fast': quick results, 'deep': comprehensive search", - ), - contextMaxCharacters: z - .number() - .optional() - .describe("Maximum characters for context string optimized for LLMs (default: 10000)"), - }), + parameters: Parameters, async execute(params, ctx) { await ctx.ask({ permission: "websearch", diff --git a/packages/opencode/test/file/index.test.ts b/packages/opencode/test/file/index.test.ts index fae3ac1f28..cd4f023cc7 100644 --- a/packages/opencode/test/file/index.test.ts +++ b/packages/opencode/test/file/index.test.ts @@ -403,7 +403,7 @@ describe("file/index Filesystem patterns", () => { const filepath = path.join(tmp.path, "file.txt") await fs.writeFile(filepath, "original\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet() + await $`git commit -m "add file"`.cwd(tmp.path).quiet() await fs.writeFile(filepath, "modified\nextra line\n", "utf-8") await Instance.provide({ @@ -441,7 +441,7 @@ describe("file/index Filesystem patterns", () => { const filepath = path.join(tmp.path, "gone.txt") await fs.writeFile(filepath, "content\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet() + await $`git commit -m "add file"`.cwd(tmp.path).quiet() await fs.rm(filepath) await Instance.provide({ @@ -460,7 +460,7 @@ describe("file/index Filesystem patterns", () => { await fs.writeFile(path.join(tmp.path, "keep.txt"), "keep\n", "utf-8") await fs.writeFile(path.join(tmp.path, "remove.txt"), "remove\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "initial"`.cwd(tmp.path).quiet() + await $`git commit -m "initial"`.cwd(tmp.path).quiet() // Modify one, delete one, add one await fs.writeFile(path.join(tmp.path, "keep.txt"), "changed\n", "utf-8") @@ -510,7 +510,7 @@ describe("file/index Filesystem patterns", () => { for (let i = 0; i < 256; i++) binaryData[i] = i await fs.writeFile(filepath, binaryData) await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "add binary"`.cwd(tmp.path).quiet() + await $`git commit -m "add binary"`.cwd(tmp.path).quiet() // Modify the binary const modified = Buffer.alloc(512) for (let i = 0; i < 512; i++) modified[i] = i % 256 @@ -826,7 +826,7 @@ describe("file/index Filesystem patterns", () => { const filepath = path.join(tmp.path, "file.txt") await fs.writeFile(filepath, "original content\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet() + await $`git commit -m "add file"`.cwd(tmp.path).quiet() await fs.writeFile(filepath, "modified content\n", "utf-8") await Instance.provide({ @@ -849,7 +849,7 @@ describe("file/index Filesystem patterns", () => { const filepath = path.join(tmp.path, "staged.txt") await fs.writeFile(filepath, "before\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet() + await $`git commit -m "add file"`.cwd(tmp.path).quiet() await fs.writeFile(filepath, "after\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() @@ -868,7 +868,7 @@ describe("file/index Filesystem patterns", () => { const filepath = path.join(tmp.path, "clean.txt") await fs.writeFile(filepath, "unchanged\n", "utf-8") await $`git add .`.cwd(tmp.path).quiet() - await $`git commit --no-gpg-sign -m "add file"`.cwd(tmp.path).quiet() + await $`git commit -m "add file"`.cwd(tmp.path).quiet() await Instance.provide({ directory: tmp.path, diff --git a/packages/opencode/test/fixture/fixture.ts b/packages/opencode/test/fixture/fixture.ts index a50e0c4f61..03713d879c 100644 --- a/packages/opencode/test/fixture/fixture.ts +++ b/packages/opencode/test/fixture/fixture.ts @@ -49,6 +49,7 @@ export async function tmpdir(options?: TmpDirOptions) { if (options?.git) { await $`git init`.cwd(dirpath).quiet() await $`git config core.fsmonitor false`.cwd(dirpath).quiet() + await $`git config commit.gpgsign false`.cwd(dirpath).quiet() await $`git config user.email "test@opencode.test"`.cwd(dirpath).quiet() await $`git config user.name "Test"`.cwd(dirpath).quiet() await $`git commit --allow-empty -m "root commit ${dirpath}"`.cwd(dirpath).quiet() @@ -100,6 +101,7 @@ export function tmpdirScoped(options?: { git?: boolean; config?: Partial { await $`git init`.cwd(tmp.path).quiet() await $`git config user.name "Test"`.cwd(tmp.path).quiet() await $`git config user.email "test@opencode.test"`.cwd(tmp.path).quiet() + await $`git config commit.gpgsign false`.cwd(tmp.path).quiet() const { project: pre } = await Project.fromDirectory(tmp.path) expect(pre.id).toBe(ProjectID.global) diff --git a/packages/opencode/test/share/share-next.test.ts b/packages/opencode/test/share/share-next.test.ts index 12d71f19a0..6619b3c605 100644 --- a/packages/opencode/test/share/share-next.test.ts +++ b/packages/opencode/test/share/share-next.test.ts @@ -272,8 +272,8 @@ describe("ShareNext", () => { diff: [ { file: "a.ts", - before: "one", - after: "two", + patch: + "Index: a.ts\n===================================================================\n--- a.ts\t\n+++ a.ts\t\n@@ -1,1 +1,1 @@\n-one\n\\ No newline at end of file\n+two\n\\ No newline at end of file\n", additions: 1, deletions: 1, status: "modified", @@ -285,8 +285,8 @@ describe("ShareNext", () => { diff: [ { file: "b.ts", - before: "old", - after: "new", + patch: + "Index: b.ts\n===================================================================\n--- b.ts\t\n+++ b.ts\t\n@@ -1,1 +1,1 @@\n-old\n\\ No newline at end of file\n+new\n\\ No newline at end of file\n", additions: 2, deletions: 0, status: "modified", @@ -304,8 +304,7 @@ describe("ShareNext", () => { type: string data: Array<{ file: string - before: string - after: string + patch: string additions: number deletions: number status?: string @@ -318,8 +317,8 @@ describe("ShareNext", () => { expect(body.data[0].data).toEqual([ { file: "b.ts", - before: "old", - after: "new", + patch: + "Index: b.ts\n===================================================================\n--- b.ts\t\n+++ b.ts\t\n@@ -1,1 +1,1 @@\n-old\n\\ No newline at end of file\n+new\n\\ No newline at end of file\n", additions: 2, deletions: 0, status: "modified", diff --git a/packages/opencode/test/snapshot/snapshot.test.ts b/packages/opencode/test/snapshot/snapshot.test.ts index 0cd9366a53..3cedfb941d 100644 --- a/packages/opencode/test/snapshot/snapshot.test.ts +++ b/packages/opencode/test/snapshot/snapshot.test.ts @@ -26,7 +26,7 @@ async function bootstrap() { await Filesystem.write(`${dir}/a.txt`, aContent) await Filesystem.write(`${dir}/b.txt`, bContent) await $`git add .`.cwd(dir).quiet() - await $`git commit --no-gpg-sign -m init`.cwd(dir).quiet() + await $`git commit -m init`.cwd(dir).quiet() return { aContent, bContent, @@ -974,8 +974,7 @@ test("diffFull with new file additions", async () => { const newFileDiff = diffs[0] expect(newFileDiff.file).toBe("new.txt") - expect(newFileDiff.before).toBe("") - expect(newFileDiff.after).toBe("new content") + expect(newFileDiff.patch).toContain("+new content") expect(newFileDiff.additions).toBe(1) expect(newFileDiff.deletions).toBe(0) }, @@ -1020,26 +1019,23 @@ test("diffFull with a large interleaved mixed diff", async () => { for (let i = 0; i < ids.length; i++) { const m = map.get(fwd("mix", `${ids[i]}-mod.txt`)) expect(m).toBeDefined() - expect(m!.before).toBe(`before-${ids[i]}-é\n🙂\nline`) - expect(m!.after).toBe(`after-${ids[i]}-é\n🚀\nline`) + expect(m!.patch).toContain(`-before-${ids[i]}-é`) + expect(m!.patch).toContain(`+after-${ids[i]}-é`) expect(m!.status).toBe("modified") const d = map.get(fwd("mix", `${ids[i]}-del.txt`)) expect(d).toBeDefined() - expect(d!.before).toBe(`gone-${ids[i]}\n你好`) - expect(d!.after).toBe("") + expect(d!.patch).toContain(`-gone-${ids[i]}`) expect(d!.status).toBe("deleted") const a = map.get(fwd("mix", `${ids[i]}-add.txt`)) expect(a).toBeDefined() - expect(a!.before).toBe("") - expect(a!.after).toBe(`new-${ids[i]}\nこんにちは`) + expect(a!.patch).toContain(`+new-${ids[i]}`) expect(a!.status).toBe("added") const b = map.get(fwd("mix", `${ids[i]}-bin.bin`)) expect(b).toBeDefined() - expect(b!.before).toBe("") - expect(b!.after).toBe("") + expect(b!.patch).toBe("") expect(b!.additions).toBe(0) expect(b!.deletions).toBe(0) expect(b!.status).toBe("modified") @@ -1092,8 +1088,8 @@ test("diffFull with file modifications", async () => { const modifiedFileDiff = diffs[0] expect(modifiedFileDiff.file).toBe("b.txt") - expect(modifiedFileDiff.before).toBe(tmp.extra.bContent) - expect(modifiedFileDiff.after).toBe("modified content") + expect(modifiedFileDiff.patch).toContain(`-${tmp.extra.bContent}`) + expect(modifiedFileDiff.patch).toContain("+modified content") expect(modifiedFileDiff.additions).toBeGreaterThan(0) expect(modifiedFileDiff.deletions).toBeGreaterThan(0) }, @@ -1118,8 +1114,7 @@ test("diffFull with file deletions", async () => { const removedFileDiff = diffs[0] expect(removedFileDiff.file).toBe("a.txt") - expect(removedFileDiff.before).toBe(tmp.extra.aContent) - expect(removedFileDiff.after).toBe("") + expect(removedFileDiff.patch).toContain(`-${tmp.extra.aContent}`) expect(removedFileDiff.additions).toBe(0) expect(removedFileDiff.deletions).toBe(1) }, @@ -1144,8 +1139,8 @@ test("diffFull with multiple line additions", async () => { const multiDiff = diffs[0] expect(multiDiff.file).toBe("multi.txt") - expect(multiDiff.before).toBe("") - expect(multiDiff.after).toBe("line1\nline2\nline3") + expect(multiDiff.patch).toContain("+line1") + expect(multiDiff.patch).toContain("+line3") expect(multiDiff.additions).toBe(3) expect(multiDiff.deletions).toBe(0) }, @@ -1171,15 +1166,13 @@ test("diffFull with addition and deletion", async () => { const addedFileDiff = diffs.find((d) => d.file === "added.txt") expect(addedFileDiff).toBeDefined() - expect(addedFileDiff!.before).toBe("") - expect(addedFileDiff!.after).toBe("added content") + expect(addedFileDiff!.patch).toContain("+added content") expect(addedFileDiff!.additions).toBe(1) expect(addedFileDiff!.deletions).toBe(0) const removedFileDiff = diffs.find((d) => d.file === "a.txt") expect(removedFileDiff).toBeDefined() - expect(removedFileDiff!.before).toBe(tmp.extra.aContent) - expect(removedFileDiff!.after).toBe("") + expect(removedFileDiff!.patch).toContain(`-${tmp.extra.aContent}`) expect(removedFileDiff!.additions).toBe(0) expect(removedFileDiff!.deletions).toBe(1) }, @@ -1263,7 +1256,7 @@ test("diffFull with binary file changes", async () => { const binaryDiff = diffs[0] expect(binaryDiff.file).toBe("binary.bin") - expect(binaryDiff.before).toBe("") + expect(binaryDiff.patch).toBe("") }, }) }) diff --git a/packages/opencode/test/tool/apply_patch.test.ts b/packages/opencode/test/tool/apply_patch.test.ts index 4e276517f1..19c8cfefd0 100644 --- a/packages/opencode/test/tool/apply_patch.test.ts +++ b/packages/opencode/test/tool/apply_patch.test.ts @@ -27,9 +27,7 @@ type AskInput = { filePath: string relativePath: string type: "add" | "update" | "delete" | "move" - diff: string - before: string - after: string + patch: string additions: number deletions: number movePath?: string @@ -112,12 +110,12 @@ describe("tool.apply_patch freeform", () => { const addFile = permissionCall.metadata.files.find((f) => f.type === "add") expect(addFile).toBeDefined() expect(addFile!.relativePath).toBe("nested/new.txt") - expect(addFile!.after).toBe("created\n") + expect(addFile!.patch).toContain("+created") const updateFile = permissionCall.metadata.files.find((f) => f.type === "update") expect(updateFile).toBeDefined() - expect(updateFile!.before).toContain("line2") - expect(updateFile!.after).toContain("changed") + expect(updateFile!.patch).toContain("-line2") + expect(updateFile!.patch).toContain("+changed") const added = await fs.readFile(path.join(fixture.path, "nested", "new.txt"), "utf-8") expect(added).toBe("created\n") @@ -151,8 +149,8 @@ describe("tool.apply_patch freeform", () => { expect(moveFile.type).toBe("move") expect(moveFile.relativePath).toBe("renamed/dir/name.txt") expect(moveFile.movePath).toBe(path.join(fixture.path, "renamed/dir/name.txt")) - expect(moveFile.before).toBe("old content\n") - expect(moveFile.after).toBe("new content\n") + expect(moveFile.patch).toContain("-old content") + expect(moveFile.patch).toContain("+new content") }, }) }) diff --git a/packages/opencode/test/tool/registry.test.ts b/packages/opencode/test/tool/registry.test.ts index c9951ef198..e3a274bb21 100644 --- a/packages/opencode/test/tool/registry.test.ts +++ b/packages/opencode/test/tool/registry.test.ts @@ -98,6 +98,37 @@ describe("tool.registry", () => { }), ) + await Bun.write( + path.join(opencodeDir, "package-lock.json"), + JSON.stringify({ + name: "custom-tools", + lockfileVersion: 3, + packages: { + "": { + dependencies: { + "@opencode-ai/plugin": "^0.0.0", + cowsay: "^1.6.0", + }, + }, + }, + }), + ) + + const cowsayDir = path.join(opencodeDir, "node_modules", "cowsay") + await fs.mkdir(cowsayDir, { recursive: true }) + await Bun.write( + path.join(cowsayDir, "package.json"), + JSON.stringify({ + name: "cowsay", + type: "module", + exports: "./index.js", + }), + ) + await Bun.write( + path.join(cowsayDir, "index.js"), + ["export function say({ text }) {", " return `moo ${text}`", "}", ""].join("\n"), + ) + await Bun.write( path.join(toolsDir, "cowsay.ts"), [ diff --git a/packages/opencode/test/tool/skill.test.ts b/packages/opencode/test/tool/skill.test.ts index ffae223f98..e6269a4f38 100644 --- a/packages/opencode/test/tool/skill.test.ts +++ b/packages/opencode/test/tool/skill.test.ts @@ -1,10 +1,11 @@ +import { Effect } from "effect" import { afterEach, describe, expect, test } from "bun:test" import path from "path" import { pathToFileURL } from "url" import type { Permission } from "../../src/permission" import type { Tool } from "../../src/tool/tool" import { Instance } from "../../src/project/instance" -import { SkillTool } from "../../src/tool/skill" +import { SkillTool, SkillDescription } from "../../src/tool/skill" import { tmpdir } from "../fixture/fixture" import { SessionID, MessageID } from "../../src/session/schema" @@ -48,9 +49,10 @@ description: Skill for tool tests. await Instance.provide({ directory: tmp.path, fn: async () => { - const tool = await SkillTool.init() - const skillPath = path.join(tmp.path, ".opencode", "skill", "tool-skill", "SKILL.md") - expect(tool.description).toContain(`**tool-skill**: Skill for tool tests.`) + const desc = await Effect.runPromise( + SkillDescription({ name: "build", mode: "primary" as const, permission: [], options: {} }), + ) + expect(desc).toContain(`**tool-skill**: Skill for tool tests.`) }, }) } finally { @@ -89,14 +91,15 @@ description: ${description} await Instance.provide({ directory: tmp.path, fn: async () => { - const first = await SkillTool.init() - const second = await SkillTool.init() + const agent = { name: "build", mode: "primary" as const, permission: [], options: {} } + const first = await Effect.runPromise(SkillDescription(agent)) + const second = await Effect.runPromise(SkillDescription(agent)) - expect(first.description).toBe(second.description) + expect(first).toBe(second) - const alpha = first.description.indexOf("**alpha-skill**: Alpha skill.") - const middle = first.description.indexOf("**middle-skill**: Middle skill.") - const zeta = first.description.indexOf("**zeta-skill**: Zeta skill.") + const alpha = first.indexOf("**alpha-skill**: Alpha skill.") + const middle = first.indexOf("**middle-skill**: Middle skill.") + const zeta = first.indexOf("**zeta-skill**: Zeta skill.") expect(alpha).toBeGreaterThan(-1) expect(middle).toBeGreaterThan(alpha) diff --git a/packages/opencode/test/tool/task.test.ts b/packages/opencode/test/tool/task.test.ts index aae48a30ab..fe936a242a 100644 --- a/packages/opencode/test/tool/task.test.ts +++ b/packages/opencode/test/tool/task.test.ts @@ -1,7 +1,8 @@ +import { Effect } from "effect" import { afterEach, describe, expect, test } from "bun:test" import { Agent } from "../../src/agent/agent" import { Instance } from "../../src/project/instance" -import { TaskTool } from "../../src/tool/task" +import { TaskDescription } from "../../src/tool/task" import { tmpdir } from "../fixture/fixture" afterEach(async () => { @@ -28,16 +29,16 @@ describe("tool.task", () => { await Instance.provide({ directory: tmp.path, fn: async () => { - const build = await Agent.get("build") - const first = await TaskTool.init({ agent: build }) - const second = await TaskTool.init({ agent: build }) + const agent = { name: "build", mode: "primary" as const, permission: [], options: {} } + const first = await Effect.runPromise(TaskDescription(agent)) + const second = await Effect.runPromise(TaskDescription(agent)) - expect(first.description).toBe(second.description) + expect(first).toBe(second) - const alpha = first.description.indexOf("- alpha: Alpha agent") - const explore = first.description.indexOf("- explore:") - const general = first.description.indexOf("- general:") - const zebra = first.description.indexOf("- zebra: Zebra agent") + const alpha = first.indexOf("- alpha: Alpha agent") + const explore = first.indexOf("- explore:") + const general = first.indexOf("- general:") + const zebra = first.indexOf("- zebra: Zebra agent") expect(alpha).toBeGreaterThan(-1) expect(explore).toBeGreaterThan(alpha) diff --git a/packages/opencode/test/tool/tool-define.test.ts b/packages/opencode/test/tool/tool-define.test.ts index 1503eed728..2ea6d56a51 100644 --- a/packages/opencode/test/tool/tool-define.test.ts +++ b/packages/opencode/test/tool/tool-define.test.ts @@ -3,7 +3,6 @@ import z from "zod" import { Tool } from "../../src/tool/tool" const params = z.object({ input: z.string() }) -const defaultArgs = { input: "test" } function makeTool(id: string, executeFn?: () => void) { return { @@ -30,36 +29,6 @@ describe("Tool.define", () => { expect(original.execute).toBe(originalExecute) }) - test("object-defined tool does not accumulate wrapper layers across init() calls", async () => { - let calls = 0 - - const tool = Tool.define( - "test-tool", - makeTool("test", () => calls++), - ) - - for (let i = 0; i < 100; i++) { - await tool.init() - } - - const resolved = await tool.init() - calls = 0 - - let stack = "" - const exec = resolved.execute - resolved.execute = async (args: any, ctx: any) => { - const result = await exec.call(resolved, args, ctx) - stack = new Error().stack || "" - return result - } - - await resolved.execute(defaultArgs, {} as any) - expect(calls).toBe(1) - - const frames = stack.split("\n").filter((l) => l.includes("tool.ts")).length - expect(frames).toBeLessThan(5) - }) - test("function-defined tool returns fresh objects and is unaffected", async () => { const tool = Tool.define("test-fn-tool", () => Promise.resolve(makeTool("test"))) @@ -77,25 +46,4 @@ describe("Tool.define", () => { expect(first).not.toBe(second) }) - - test("validation still works after many init() calls", async () => { - const tool = Tool.define("test-validation", { - description: "validation test", - parameters: z.object({ count: z.number().int().positive() }), - async execute(args) { - return { title: "test", output: String(args.count), metadata: {} } - }, - }) - - for (let i = 0; i < 100; i++) { - await tool.init() - } - - const resolved = await tool.init() - - const result = await resolved.execute({ count: 42 }, {} as any) - expect(result.output).toBe("42") - - await expect(resolved.execute({ count: -1 }, {} as any)).rejects.toThrow("invalid arguments") - }) }) diff --git a/packages/opencode/test/tool/webfetch.test.ts b/packages/opencode/test/tool/webfetch.test.ts index 088f3dd16d..5233f10816 100644 --- a/packages/opencode/test/tool/webfetch.test.ts +++ b/packages/opencode/test/tool/webfetch.test.ts @@ -17,6 +17,8 @@ const ctx = { ask: async () => {}, } +type TimerID = ReturnType + async function withFetch( mockFetch: (input: string | URL | Request, init?: RequestInit) => Promise, fn: () => Promise, @@ -30,6 +32,32 @@ async function withFetch( } } +async function withTimers(fn: (state: { ids: TimerID[]; cleared: TimerID[] }) => Promise) { + const set = globalThis.setTimeout + const clear = globalThis.clearTimeout + const ids: TimerID[] = [] + const cleared: TimerID[] = [] + + globalThis.setTimeout = ((...args: Parameters) => { + const id = set(...args) + ids.push(id) + return id + }) as typeof setTimeout + + globalThis.clearTimeout = ((id?: TimerID) => { + if (id !== undefined) cleared.push(id) + return clear(id) + }) as typeof clearTimeout + + try { + await fn({ ids, cleared }) + } finally { + ids.forEach(clear) + globalThis.setTimeout = set + globalThis.clearTimeout = clear + } +} + describe("tool.webfetch", () => { test("returns image responses as file attachments", async () => { const bytes = new Uint8Array([137, 80, 78, 71, 13, 10, 26, 10]) @@ -98,4 +126,28 @@ describe("tool.webfetch", () => { }, ) }) + + test("clears timeout when fetch rejects", async () => { + await withTimers(async ({ ids, cleared }) => { + await withFetch( + async () => { + throw new Error("boom") + }, + async () => { + await Instance.provide({ + directory: projectRoot, + fn: async () => { + const webfetch = await WebFetchTool.init() + await expect( + webfetch.execute({ url: "https://example.com/file.txt", format: "text" }, ctx), + ).rejects.toThrow("boom") + }, + }) + }, + ) + + expect(ids).toHaveLength(1) + expect(cleared).toContain(ids[0]) + }) + }) }) diff --git a/packages/plugin/package.json b/packages/plugin/package.json index 0569a0a7cc..6e3fc8348a 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.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 03ff4b46b3..c33b561d18 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.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/src/v2/client.ts b/packages/sdk/js/src/v2/client.ts index e230a4b5dc..67fe1de32f 100644 --- a/packages/sdk/js/src/v2/client.ts +++ b/packages/sdk/js/src/v2/client.ts @@ -77,5 +77,6 @@ export function createOpencodeClient(config?: Config & { directory?: string; exp workspace: config?.experimental_workspaceID, }), ) - return new OpencodeClient({ client }) + const result = new OpencodeClient({ client }) + return result } diff --git a/packages/sdk/js/src/v2/data.ts b/packages/sdk/js/src/v2/data.ts new file mode 100644 index 0000000000..baae6f278d --- /dev/null +++ b/packages/sdk/js/src/v2/data.ts @@ -0,0 +1,32 @@ +import type { Part, UserMessage } from "./client.js" + +export const message = { + user(input: Omit & { parts: Omit[] }): { + info: UserMessage + parts: Part[] + } { + const { parts, ...rest } = input + + const info: UserMessage = { + ...rest, + id: "asdasd", + time: { + created: Date.now(), + }, + role: "user", + } + + return { + info, + parts: input.parts.map( + (part) => + ({ + ...part, + id: "asdasd", + messageID: info.id, + sessionID: info.sessionID, + }) as Part, + ), + } + }, +} diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index fc1616c4fd..0a9aa4358e 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -347,10 +347,9 @@ export type EventCommandExecuted = { } } -export type FileDiff = { +export type SnapshotFileDiff = { file: string - before: string - after: string + patch: string additions: number deletions: number status?: "added" | "deleted" | "modified" @@ -360,7 +359,7 @@ export type EventSessionDiff = { type: "session.diff" properties: { sessionID: string - diff: Array + diff: Array } } @@ -542,7 +541,7 @@ export type UserMessage = { summary?: { title?: string body?: string - diffs: Array + diffs: Array } agent: string model: { @@ -917,7 +916,7 @@ export type Session = { additions: number deletions: number files: number - diffs?: Array + diffs?: Array } share?: { url: string @@ -1078,7 +1077,7 @@ export type SyncEventSessionUpdated = { additions: number deletions: number files: number - diffs?: Array + diffs?: Array } | null share?: { url: string | null @@ -1803,7 +1802,7 @@ export type GlobalSession = { additions: number deletions: number files: number - diffs?: Array + diffs?: Array } share?: { url: string @@ -2009,6 +2008,14 @@ export type VcsInfo = { default_branch?: string } +export type VcsFileDiff = { + file: string + patch: string + additions: number + deletions: number + status?: "added" | "deleted" | "modified" +} + export type Command = { name: string description?: string @@ -3503,7 +3510,7 @@ export type SessionDiffResponses = { /** * Successfully retrieved diff */ - 200: Array + 200: Array } export type SessionDiffResponse = SessionDiffResponses[keyof SessionDiffResponses] @@ -5159,7 +5166,7 @@ export type VcsDiffResponses = { /** * VCS diff */ - 200: Array + 200: Array } export type VcsDiffResponse = VcsDiffResponses[keyof VcsDiffResponses] diff --git a/packages/sdk/js/src/v2/index.ts b/packages/sdk/js/src/v2/index.ts index d044f5ad66..d514784bc2 100644 --- a/packages/sdk/js/src/v2/index.ts +++ b/packages/sdk/js/src/v2/index.ts @@ -5,6 +5,9 @@ import { createOpencodeClient } from "./client.js" import { createOpencodeServer } from "./server.js" import type { ServerOptions } from "./server.js" +export * as data from "./data.js" +import * as data from "./data.js" + export async function createOpencode(options?: ServerOptions) { const server = await createOpencodeServer({ ...options, diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index 5007e78e8b..207b400a7d 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -3071,7 +3071,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/SnapshotFileDiff" } } } @@ -7032,7 +7032,7 @@ "schema": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/VcsFileDiff" } } } @@ -8146,16 +8146,13 @@ }, "required": ["type", "properties"] }, - "FileDiff": { + "SnapshotFileDiff": { "type": "object", "properties": { "file": { "type": "string" }, - "before": { - "type": "string" - }, - "after": { + "patch": { "type": "string" }, "additions": { @@ -8169,7 +8166,7 @@ "enum": ["added", "deleted", "modified"] } }, - "required": ["file", "before", "after", "additions", "deletions"] + "required": ["file", "patch", "additions", "deletions"] }, "Event.session.diff": { "type": "object", @@ -8188,7 +8185,7 @@ "diff": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/SnapshotFileDiff" } } }, @@ -8700,7 +8697,7 @@ "diffs": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/SnapshotFileDiff" } } }, @@ -9842,7 +9839,7 @@ "diffs": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/SnapshotFileDiff" } } }, @@ -10372,7 +10369,7 @@ "diffs": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/SnapshotFileDiff" } } }, @@ -12122,7 +12119,7 @@ "diffs": { "type": "array", "items": { - "$ref": "#/components/schemas/FileDiff" + "$ref": "#/components/schemas/SnapshotFileDiff" } } }, @@ -12760,6 +12757,28 @@ } } }, + "VcsFileDiff": { + "type": "object", + "properties": { + "file": { + "type": "string" + }, + "patch": { + "type": "string" + }, + "additions": { + "type": "number" + }, + "deletions": { + "type": "number" + }, + "status": { + "type": "string", + "enum": ["added", "deleted", "modified"] + } + }, + "required": ["file", "patch", "additions", "deletions"] + }, "Command": { "type": "object", "properties": { diff --git a/packages/slack/package.json b/packages/slack/package.json index dad6eac206..0e77525273 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/ui/package.json b/packages/ui/package.json index 64520f707c..3693175b8a 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.3.17", + "version": "1.4.0", "type": "module", "license": "MIT", "exports": { @@ -53,6 +53,7 @@ "@solid-primitives/resize-observer": "2.1.3", "@solidjs/meta": "catalog:", "@solidjs/router": "catalog:", + "diff": "catalog:", "dompurify": "3.3.1", "fuzzysort": "catalog:", "katex": "0.16.27", diff --git a/packages/ui/src/components/file-media.tsx b/packages/ui/src/components/file-media.tsx index 2fd54588a3..f066019d72 100644 --- a/packages/ui/src/components/file-media.tsx +++ b/packages/ui/src/components/file-media.tsx @@ -16,6 +16,7 @@ export type FileMediaOptions = { current?: unknown before?: unknown after?: unknown + deleted?: boolean readFile?: (path: string) => Promise onLoad?: () => void onError?: (ctx: { kind: "image" | "audio" | "svg" }) => void @@ -49,6 +50,7 @@ export function FileMedia(props: { media?: FileMediaOptions; fallback: () => JSX const media = cfg() const k = kind() if (!media || !k) return false + if (media.deleted) return true if (k === "svg") return false if (media.current !== undefined) return false return !hasMediaValue(media.after as any) && hasMediaValue(media.before as any) diff --git a/packages/ui/src/components/file-ssr.tsx b/packages/ui/src/components/file-ssr.tsx index 9526907831..fed5c89315 100644 --- a/packages/ui/src/components/file-ssr.tsx +++ b/packages/ui/src/components/file-ssr.tsx @@ -1,5 +1,5 @@ import { DIFFS_TAG_NAME, FileDiff, VirtualizedFileDiff } from "@pierre/diffs" -import { type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" +import { type PreloadFileDiffResult, type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { createEffect, onCleanup, onMount, Show, splitProps } from "solid-js" import { Dynamic, isServer } from "solid-js/web" import { useWorkerPool } from "../context/worker-pool" @@ -16,8 +16,10 @@ import { import { acquireVirtualizer, virtualMetrics } from "../pierre/virtualizer" import { File, type DiffFileProps, type FileProps } from "./file" +type DiffPreload = PreloadMultiFileDiffResult | PreloadFileDiffResult + type SSRDiffFileProps = DiffFileProps & { - preloadedDiff: PreloadMultiFileDiffResult + preloadedDiff: DiffPreload } function DiffSSRViewer(props: SSRDiffFileProps) { @@ -32,6 +34,7 @@ function DiffSSRViewer(props: SSRDiffFileProps) { const [local, others] = splitProps(props, [ "mode", "media", + "fileDiff", "before", "after", "class", @@ -90,12 +93,13 @@ function DiffSSRViewer(props: SSRDiffFileProps) { onCleanup(observeViewerScheme(() => fileDiffRef)) const virtualizer = getVirtualizer() + const annotations = local.annotations ?? local.preloadedDiff.annotations ?? [] fileDiffInstance = virtualizer ? new VirtualizedFileDiff( { ...createDefaultOptions(props.diffStyle), ...others, - ...local.preloadedDiff, + ...(local.preloadedDiff.options ?? {}), }, virtualizer, virtualMetrics, @@ -105,7 +109,7 @@ function DiffSSRViewer(props: SSRDiffFileProps) { { ...createDefaultOptions(props.diffStyle), ...others, - ...local.preloadedDiff, + ...(local.preloadedDiff.options ?? {}), }, workerPool, ) @@ -114,13 +118,24 @@ function DiffSSRViewer(props: SSRDiffFileProps) { // @ts-expect-error private field required for hydration fileDiffInstance.fileContainer = fileDiffRef - fileDiffInstance.hydrate({ - oldFile: local.before, - newFile: local.after, - lineAnnotations: local.annotations ?? [], - fileContainer: fileDiffRef, - containerWrapper: container, - }) + fileDiffInstance.hydrate( + local.fileDiff + ? { + fileDiff: local.fileDiff, + lineAnnotations: annotations, + fileContainer: fileDiffRef, + containerWrapper: container, + prerenderedHTML: local.preloadedDiff.prerenderedHTML, + } + : { + oldFile: local.before, + newFile: local.after, + lineAnnotations: annotations, + fileContainer: fileDiffRef, + containerWrapper: container, + prerenderedHTML: local.preloadedDiff.prerenderedHTML, + }, + ) notifyRendered() }) diff --git a/packages/ui/src/components/file.tsx b/packages/ui/src/components/file.tsx index fb488729e2..b78f0bae44 100644 --- a/packages/ui/src/components/file.tsx +++ b/packages/ui/src/components/file.tsx @@ -3,6 +3,7 @@ import { DEFAULT_VIRTUAL_FILE_METRICS, type DiffLineAnnotation, type FileContents, + type FileDiffMetadata, File as PierreFile, type FileDiffOptions, FileDiff, @@ -14,7 +15,7 @@ import { VirtualizedFileDiff, Virtualizer, } from "@pierre/diffs" -import { type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" +import { type PreloadFileDiffResult, type PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { createMediaQuery } from "@solid-primitives/media" import { makeEventListener } from "@solid-primitives/event-listener" import { ComponentProps, createEffect, createMemo, createSignal, onCleanup, onMount, Show, splitProps } from "solid-js" @@ -80,15 +81,29 @@ export type TextFileProps = FileOptions & preloadedDiff?: PreloadMultiFileDiffResult } -export type DiffFileProps = FileDiffOptions & +type DiffPreload = PreloadMultiFileDiffResult | PreloadFileDiffResult + +type DiffBaseProps = FileDiffOptions & SharedProps & { mode: "diff" - before: FileContents - after: FileContents annotations?: DiffLineAnnotation[] - preloadedDiff?: PreloadMultiFileDiffResult + preloadedDiff?: DiffPreload } +type DiffPairProps = DiffBaseProps & { + before: FileContents + after: FileContents + fileDiff?: undefined +} + +type DiffPatchProps = DiffBaseProps & { + fileDiff: FileDiffMetadata + before?: undefined + after?: undefined +} + +export type DiffFileProps = DiffPairProps | DiffPatchProps + export type FileProps = TextFileProps | DiffFileProps const sharedKeys = [ @@ -108,7 +123,7 @@ const sharedKeys = [ ] as const const textKeys = ["file", ...sharedKeys] as const -const diffKeys = ["before", "after", ...sharedKeys] as const +const diffKeys = ["fileDiff", "before", "after", ...sharedKeys] as const // --------------------------------------------------------------------------- // Shared viewer hook @@ -976,6 +991,12 @@ function DiffViewer(props: DiffFileProps) { const virtuals = createSharedVirtualStrategy(() => viewer.container) const large = createMemo(() => { + if (local.fileDiff) { + const before = local.fileDiff.deletionLines.join("") + const after = local.fileDiff.additionLines.join("") + return Math.max(before.length, after.length) > 500_000 + } + const before = typeof local.before?.contents === "string" ? local.before.contents : "" const after = typeof local.after?.contents === "string" ? local.after.contents : "" return Math.max(before.length, after.length) > 500_000 @@ -1054,6 +1075,17 @@ function DiffViewer(props: DiffFileProps) { instance = value }, draw: (value) => { + if (local.fileDiff) { + value.render({ + fileDiff: local.fileDiff, + lineAnnotations: [], + containerWrapper: viewer.container, + }) + return + } + + if (!local.before || !local.after) return + value.render({ oldFile: { ...local.before, contents: beforeContents, cacheKey: cacheKey(beforeContents) }, newFile: { ...local.after, contents: afterContents, cacheKey: cacheKey(afterContents) }, diff --git a/packages/ui/src/components/session-diff.test.ts b/packages/ui/src/components/session-diff.test.ts new file mode 100644 index 0000000000..463a729778 --- /dev/null +++ b/packages/ui/src/components/session-diff.test.ts @@ -0,0 +1,37 @@ +import { describe, expect, test } from "bun:test" +import { normalize, text } from "./session-diff" + +describe("session diff", () => { + test("keeps unified patch content", () => { + const diff = { + file: "a.ts", + patch: + "Index: a.ts\n===================================================================\n--- a.ts\t\n+++ a.ts\t\n@@ -1,2 +1,2 @@\n one\n-two\n+three\n", + additions: 1, + deletions: 1, + status: "modified" as const, + } + const view = normalize(diff) + + expect(view.patch).toBe(diff.patch) + expect(view.fileDiff.name).toBe("a.ts") + expect(text(view, "deletions")).toBe("one\ntwo\n") + expect(text(view, "additions")).toBe("one\nthree\n") + }) + + test("converts legacy content into a patch", () => { + const diff = { + file: "a.ts", + before: "one\n", + after: "two\n", + additions: 1, + deletions: 1, + status: "modified" as const, + } + const view = normalize(diff) + + expect(view.patch).toContain("@@ -1,1 +1,1 @@") + expect(text(view, "deletions")).toBe("one\n") + expect(text(view, "additions")).toBe("two\n") + }) +}) diff --git a/packages/ui/src/components/session-diff.ts b/packages/ui/src/components/session-diff.ts new file mode 100644 index 0000000000..cc2b1ce527 --- /dev/null +++ b/packages/ui/src/components/session-diff.ts @@ -0,0 +1,83 @@ +import { parsePatchFiles, type FileDiffMetadata } from "@pierre/diffs" +import { sampledChecksum } from "@opencode-ai/util/encode" +import { formatPatch, structuredPatch } from "diff" +import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2" + +type LegacyDiff = { + file: string + patch?: string + before?: string + after?: string + additions: number + deletions: number + status?: "added" | "deleted" | "modified" +} + +type ReviewDiff = SnapshotFileDiff | VcsFileDiff | LegacyDiff + +export type ViewDiff = { + file: string + patch: string + additions: number + deletions: number + status?: "added" | "deleted" | "modified" + fileDiff: FileDiffMetadata +} + +const cache = new Map() + +function empty(file: string, key: string) { + return { + name: file, + type: "change", + hunks: [], + splitLineCount: 0, + unifiedLineCount: 0, + isPartial: true, + deletionLines: [], + additionLines: [], + cacheKey: key, + } satisfies FileDiffMetadata +} + +function patch(diff: ReviewDiff) { + if (typeof diff.patch === "string") return diff.patch + return formatPatch( + structuredPatch( + diff.file, + diff.file, + "before" in diff && typeof diff.before === "string" ? diff.before : "", + "after" in diff && typeof diff.after === "string" ? diff.after : "", + "", + "", + { context: Number.MAX_SAFE_INTEGER }, + ), + ) +} + +function file(file: string, patch: string) { + const hit = cache.get(patch) + if (hit) return hit + + const key = sampledChecksum(patch) ?? file + const value = parsePatchFiles(patch, key).flatMap((item) => item.files)[0] ?? empty(file, key) + cache.set(patch, value) + return value +} + +export function normalize(diff: ReviewDiff): ViewDiff { + const next = patch(diff) + return { + file: diff.file, + patch: next, + additions: diff.additions, + deletions: diff.deletions, + status: diff.status, + fileDiff: file(diff.file, next), + } +} + +export function text(diff: ViewDiff, side: "deletions" | "additions") { + if (side === "deletions") return diff.fileDiff.deletionLines.join("") + return diff.fileDiff.additionLines.join("") +} diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx index 3b582d66f9..90da853efc 100644 --- a/packages/ui/src/components/session-review.tsx +++ b/packages/ui/src/components/session-review.tsx @@ -15,7 +15,7 @@ import { getDirectory, getFilename } from "@opencode-ai/util/path" import { checksum } from "@opencode-ai/util/encode" import { createEffect, createMemo, For, Match, onCleanup, Show, Switch, untrack, type JSX } from "solid-js" import { createStore } from "solid-js/store" -import { type FileContent, type FileDiff } from "@opencode-ai/sdk/v2" +import { type FileContent, type SnapshotFileDiff, type VcsFileDiff } from "@opencode-ai/sdk/v2" import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" import { type SelectedLineRange } from "@pierre/diffs" import { Dynamic } from "solid-js/web" @@ -23,6 +23,7 @@ import { mediaKindFromPath } from "../pierre/media" import { cloneSelectedLineRange, previewSelectedLines } from "../pierre/selection-bridge" import { createLineCommentController } from "./line-comment-annotations" import type { LineCommentEditorProps } from "./line-comment" +import { normalize, text, type ViewDiff } from "./session-diff" const MAX_DIFF_CHANGED_LINES = 500 const REVIEW_MOUNT_MARGIN = 300 @@ -61,7 +62,8 @@ export type SessionReviewCommentActions = { export type SessionReviewFocus = { file: string; id: string } -type ReviewDiff = FileDiff & { preloaded?: PreloadMultiFileDiffResult } +type ReviewDiff = (SnapshotFileDiff | VcsFileDiff) & { preloaded?: PreloadMultiFileDiffResult } +type Item = ViewDiff & { preloaded?: PreloadMultiFileDiffResult } export interface SessionReviewProps { title?: JSX.Element @@ -155,8 +157,8 @@ export const SessionReview = (props: SessionReviewProps) => { const opened = () => store.opened const open = () => props.open ?? store.open - const files = createMemo(() => props.diffs.map((diff) => diff.file)) - const diffs = createMemo(() => new Map(props.diffs.map((diff) => [diff.file, diff] as const))) + const items = createMemo(() => props.diffs.map((diff) => ({ ...normalize(diff), preloaded: diff.preloaded }))) + const files = createMemo(() => items().map((diff) => diff.file)) const grouped = createMemo(() => { const next = new Map() for (const comment of props.comments ?? []) { @@ -246,10 +248,10 @@ export const SessionReview = (props: SessionReviewProps) => { const selectionSide = (range: SelectedLineRange) => range.endSide ?? range.side ?? "additions" - const selectionPreview = (diff: FileDiff, range: SelectedLineRange) => { + const selectionPreview = (diff: ViewDiff, range: SelectedLineRange) => { const side = selectionSide(range) - const contents = side === "deletions" ? diff.before : diff.after - if (typeof contents !== "string" || contents.length === 0) return undefined + const contents = text(diff, side) + if (contents.length === 0) return undefined return previewSelectedLines(contents, range) } @@ -359,7 +361,7 @@ export const SessionReview = (props: SessionReviewProps) => {
    - + {(diff) => { let wrapper: HTMLDivElement | undefined const file = diff.file @@ -371,8 +373,8 @@ export const SessionReview = (props: SessionReviewProps) => { const comments = createMemo(() => grouped().get(file) ?? []) const commentedLines = createMemo(() => comments().map((c) => c.selection)) - const beforeText = () => (typeof diff.before === "string" ? diff.before : "") - const afterText = () => (typeof diff.after === "string" ? diff.after : "") + const beforeText = () => text(diff, "deletions") + const afterText = () => text(diff, "additions") const changedLines = () => diff.additions + diff.deletions const mediaKind = createMemo(() => mediaKindFromPath(file)) @@ -581,6 +583,7 @@ export const SessionReview = (props: SessionReviewProps) => { { @@ -596,20 +599,11 @@ export const SessionReview = (props: SessionReviewProps) => { renderHoverUtility={props.onLineComment ? commentsUi.renderHoverUtility : undefined} selectedLines={selectedLines()} commentedLines={commentedLines()} - before={{ - name: file, - contents: typeof diff.before === "string" ? diff.before : "", - }} - after={{ - name: file, - contents: typeof diff.after === "string" ? diff.after : "", - }} media={{ mode: "auto", path: file, - before: diff.before, - after: diff.after, - readFile: props.readFile, + deleted: diff.status === "deleted", + readFile: diff.status === "deleted" ? undefined : props.readFile, }} /> diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index c20e5fb1ce..bb699a77e2 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -1,4 +1,9 @@ -import { AssistantMessage, type FileDiff, Message as MessageType, Part as PartType } from "@opencode-ai/sdk/v2/client" +import { + AssistantMessage, + type SnapshotFileDiff, + Message as MessageType, + Part as PartType, +} from "@opencode-ai/sdk/v2/client" import type { SessionStatus } from "@opencode-ai/sdk/v2" import { useData } from "../context" import { useFileComponent } from "../context/file" @@ -19,6 +24,7 @@ import { SessionRetry } from "./session-retry" import { TextReveal } from "./text-reveal" import { createAutoScroll } from "../hooks" import { useI18n } from "../context/i18n" +import { normalize } from "./session-diff" function record(value: unknown): value is Record { return !!value && typeof value === "object" && !Array.isArray(value) @@ -163,7 +169,7 @@ export function SessionTurn( const emptyMessages: MessageType[] = [] const emptyParts: PartType[] = [] const emptyAssistant: AssistantMessage[] = [] - const emptyDiffs: FileDiff[] = [] + const emptyDiffs: SnapshotFileDiff[] = [] const idle = { type: "idle" as const } const allMessages = createMemo(() => props.messages ?? list(data.store.message?.[props.sessionID], emptyMessages)) @@ -232,7 +238,7 @@ export function SessionTurn( const seen = new Set() return files - .reduceRight((result, diff) => { + .reduceRight((result, diff) => { if (seen.has(diff.file)) return result seen.add(diff.file) result.push(diff) @@ -447,6 +453,7 @@ export function SessionTurn( > {(diff) => { + const view = normalize(diff) const active = createMemo(() => expanded().includes(diff.file)) const [shown, setShown] = createSignal(false) @@ -495,12 +502,7 @@ export function SessionTurn(
    - +
    diff --git a/packages/ui/src/context/data.tsx b/packages/ui/src/context/data.tsx index 93368c2a05..632bed0cfa 100644 --- a/packages/ui/src/context/data.tsx +++ b/packages/ui/src/context/data.tsx @@ -1,4 +1,4 @@ -import type { Message, Session, Part, FileDiff, SessionStatus, ProviderListResponse } from "@opencode-ai/sdk/v2" +import type { Message, Session, Part, SnapshotFileDiff, SessionStatus, ProviderListResponse } from "@opencode-ai/sdk/v2" import { createSimpleContext } from "./helper" import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr" @@ -13,7 +13,7 @@ type Data = { [sessionID: string]: SessionStatus } session_diff: { - [sessionID: string]: FileDiff[] + [sessionID: string]: SnapshotFileDiff[] } session_diff_preload?: { [sessionID: string]: PreloadMultiFileDiffResult[] diff --git a/packages/util/package.json b/packages/util/package.json index 0eab52cccc..8b44dc7ae6 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/util", - "version": "1.3.17", + "version": "1.4.0", "private": true, "type": "module", "license": "MIT", diff --git a/packages/web/package.json b/packages/web/package.json index 77f54ef67c..8f963eedf4 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.3.17", + "version": "1.4.0", "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 2fbeb65315..34ae96eaaa 100644 --- a/packages/web/src/content/docs/ar/go.mdx +++ b/packages/web/src/content/docs/ar/go.mdx @@ -54,6 +54,7 @@ OpenCode Go حاليًا في المرحلة التجريبية. تشمل قائمة النماذج الحالية: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go حاليًا في المرحلة التجريبية. - **الحد الأسبوعي** — استخدام بقيمة $30 - **الحد الشهري** — استخدام بقيمة $60 -تُحدَّد الحدود بالقيمة بالدولار. وهذا يعني أن عدد طلباتك الفعلي يعتمد على النموذج الذي تستخدمه. تتيح النماذج الأقل تكلفة مثل MiniMax M2.5 عددًا أكبر من الطلبات، بينما تتيح النماذج الأعلى تكلفة مثل GLM-5 عددًا أقل. +تُحدَّد الحدود بالقيمة بالدولار. وهذا يعني أن عدد طلباتك الفعلي يعتمد على النموذج الذي تستخدمه. تتيح النماذج الأقل تكلفة مثل MiniMax M2.5 عددًا أكبر من الطلبات، بينما تتيح النماذج الأعلى تكلفة مثل GLM-5.1 عددًا أقل. يوضح الجدول أدناه عددًا تقديريًا للطلبات بناءً على أنماط استخدام Go المعتادة: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| الطلبات لكل 5 ساعات | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| الطلبات في الأسبوع | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| الطلبات في الشهر | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| الطلبات لكل 5 ساعات | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| الطلبات في الأسبوع | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| الطلبات في الشهر | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | تستند التقديرات إلى متوسطات أنماط الطلبات المرصودة: -- GLM-5 — ‏700 input، و52,000 cached، و150 output tokens لكل طلب +- GLM-5/5.1 — ‏700 input، و52,000 cached، و150 output tokens لكل طلب - Kimi K2.5 — ‏870 input، و55,000 cached، و200 output tokens لكل طلب - MiniMax M2.7/M2.5 — ‏300 input، و55,000 cached، و125 output tokens لكل طلب - MiMo-V2-Pro — ‏350 input، و41,000 cached، و250 output tokens لكل طلب @@ -112,6 +113,7 @@ OpenCode Go حاليًا في المرحلة التجريبية. | Model | Model ID | Endpoint | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/ar/keybinds.mdx b/packages/web/src/content/docs/ar/keybinds.mdx index 986313a5b5..d40d49729e 100644 --- a/packages/web/src/content/docs/ar/keybinds.mdx +++ b/packages/web/src/content/docs/ar/keybinds.mdx @@ -53,6 +53,7 @@ description: خصّص اختصارات لوحة المفاتيح. "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/ar/zen.mdx b/packages/web/src/content/docs/ar/zen.mdx index 288c44d89a..27a2c8132d 100644 --- a/packages/web/src/content/docs/ar/zen.mdx +++ b/packages/web/src/content/docs/ar/zen.mdx @@ -86,6 +86,7 @@ OpenCode Zen هي بوابة AI تتيح لك الوصول إلى هذه الن | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -121,6 +122,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/bs/go.mdx b/packages/web/src/content/docs/bs/go.mdx index a4ec36069c..1e4371c12d 100644 --- a/packages/web/src/content/docs/bs/go.mdx +++ b/packages/web/src/content/docs/bs/go.mdx @@ -64,6 +64,7 @@ Samo jedan član po radnom prostoru (workspace) može se pretplatiti na OpenCode Trenutna lista modela uključuje: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ OpenCode Go uključuje sljedeća ograničenja: - **Sedmično ograničenje** — $30 potrošnje - **Mjesečno ograničenje** — $60 potrošnje -Ograničenja su definisana u dolarskoj vrijednosti. To znači da vaš stvarni broj zahtjeva zavisi od modela koji koristite. Jeftiniji modeli poput MiniMax M2.5 omogućavaju više zahtjeva, dok skuplji modeli poput GLM-5 omogućavaju manje. +Ograničenja su definisana u dolarskoj vrijednosti. To znači da vaš stvarni broj zahtjeva zavisi od modela koji koristite. Jeftiniji modeli poput MiniMax M2.5 omogućavaju više zahtjeva, dok skuplji modeli poput GLM-5.1 omogućavaju manje. Tabela ispod pruža procijenjeni broj zahtjeva na osnovu tipičnih obrazaca korištenja Go pretplate: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------ | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| zahtjeva na 5 sati | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| zahtjeva sedmično | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| zahtjeva mjesečno | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------ | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| zahtjeva na 5 sati | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| zahtjeva sedmično | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| zahtjeva mjesečno | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | Procjene se zasnivaju na zapaženim prosječnim obrascima zahtjeva: -- GLM-5 — 700 ulaznih (input), 52,000 keširanih, 150 izlaznih (output) tokena po zahtjevu +- GLM-5/5.1 — 700 ulaznih (input), 52,000 keširanih, 150 izlaznih (output) tokena po zahtjevu - Kimi K2.5 — 870 ulaznih, 55,000 keširanih, 200 izlaznih tokena po zahtjevu - MiniMax M2.7/M2.5 — 300 ulaznih, 55,000 keširanih, 125 izlaznih tokena po zahtjevu - MiMo-V2-Pro — 350 ulaznih, 41,000 keširanih, 250 izlaznih tokena po zahtjevu @@ -124,6 +125,7 @@ Također možete pristupiti Go modelima putem sljedećih API endpointa. | Model | Model ID | Endpoint | AI SDK Paket | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/bs/keybinds.mdx b/packages/web/src/content/docs/bs/keybinds.mdx index a70fdedaef..31fed59005 100644 --- a/packages/web/src/content/docs/bs/keybinds.mdx +++ b/packages/web/src/content/docs/bs/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode ima listu veza tipki koje možete prilagoditi putem `tui.json`. "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/bs/zen.mdx b/packages/web/src/content/docs/bs/zen.mdx index 7222fd2d4c..d8b258f471 100644 --- a/packages/web/src/content/docs/bs/zen.mdx +++ b/packages/web/src/content/docs/bs/zen.mdx @@ -91,6 +91,7 @@ Našim modelima možete pristupiti i preko sljedećih API endpointa. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ Podržavamo pay-as-you-go model. Ispod su cijene **po 1M tokena**. | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/da/go.mdx b/packages/web/src/content/docs/da/go.mdx index 145c301bc6..9cc45443ee 100644 --- a/packages/web/src/content/docs/da/go.mdx +++ b/packages/web/src/content/docs/da/go.mdx @@ -64,6 +64,7 @@ Kun ét medlem per arbejdsområde kan abonnere på OpenCode Go. Den nuværende liste over modeller inkluderer: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ OpenCode Go inkluderer følgende grænser: - **Ugentlig grænse** — forbrug for $30 - **Månedlig grænse** — forbrug for $60 -Grænserne er defineret i dollarværdi. Det betyder, at dit faktiske antal anmodninger afhænger af den model, du bruger. Billigere modeller som MiniMax M2.5 tillader flere anmodninger, mens dyrere modeller som GLM-5 tillader færre. +Grænserne er defineret i dollarværdi. Det betyder, at dit faktiske antal anmodninger afhænger af den model, du bruger. Billigere modeller som MiniMax M2.5 tillader flere anmodninger, mens dyrere modeller som GLM-5.1 tillader færre. Tabellen nedenfor giver et estimeret antal anmodninger baseret på typiske Go-forbrugsmønstre: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ----------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| anmodninger pr. 5 timer | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | -| anmodninger pr. uge | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | -| anmodninger pr. måned | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ----------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| anmodninger pr. 5 timer | 880 | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | +| anmodninger pr. uge | 2.150 | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | +| anmodninger pr. måned | 4.300 | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | Estimaterne er baseret på observerede gennemsnitlige anmodningsmønstre: -- GLM-5 — 700 input, 52.000 cachelagrede, 150 output-tokens pr. anmodning +- GLM-5/5.1 — 700 input, 52.000 cachelagrede, 150 output-tokens pr. anmodning - Kimi K2.5 — 870 input, 55.000 cachelagrede, 200 output-tokens pr. anmodning - MiniMax M2.7/M2.5 — 300 input, 55.000 cachelagrede, 125 output-tokens pr. anmodning - MiMo-V2-Pro — 350 input, 41.000 cachelagrede, 250 output-tokens pr. anmodning @@ -124,6 +125,7 @@ Du kan også få adgang til Go-modeller gennem følgende API-endpoints. | Model | Model ID | Endpoint | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/da/keybinds.mdx b/packages/web/src/content/docs/da/keybinds.mdx index 237c36f775..7b2f2a7f31 100644 --- a/packages/web/src/content/docs/da/keybinds.mdx +++ b/packages/web/src/content/docs/da/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode har en liste over nøglebindinger, som du kan tilpasse gennem `tui.json "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/da/zen.mdx b/packages/web/src/content/docs/da/zen.mdx index 4d92a60fac..3660e528dc 100644 --- a/packages/web/src/content/docs/da/zen.mdx +++ b/packages/web/src/content/docs/da/zen.mdx @@ -91,6 +91,7 @@ Du kan også få adgang til vores modeller gennem følgende API-endpoints. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ Vi understøtter en pay-as-you-go-model. Nedenfor er priserne **pr. 1M tokens**. | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/de/go.mdx b/packages/web/src/content/docs/de/go.mdx index 1bf0e3dafa..95237ea82a 100644 --- a/packages/web/src/content/docs/de/go.mdx +++ b/packages/web/src/content/docs/de/go.mdx @@ -56,6 +56,7 @@ Nur ein Mitglied pro Workspace kann OpenCode Go abonnieren. Die aktuelle Liste der Modelle umfasst: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -74,19 +75,19 @@ OpenCode Go beinhaltet die folgenden Limits: - **Wöchentliches Limit** — 30 $ Nutzung - **Monatliches Limit** — 60 $ Nutzung -Limits sind in Dollarwerten definiert. Das bedeutet, dass die tatsächliche Anzahl deiner Anfragen von dem von dir genutzten Modell abhängt. Günstigere Modelle wie MiniMax M2.5 erlauben mehr Anfragen, während teurere Modelle wie GLM-5 weniger erlauben. +Limits sind in Dollarwerten definiert. Das bedeutet, dass die tatsächliche Anzahl deiner Anfragen von dem von dir genutzten Modell abhängt. Günstigere Modelle wie MiniMax M2.5 erlauben mehr Anfragen, während teurere Modelle wie GLM-5.1 weniger erlauben. Die folgende Tabelle zeigt eine geschätzte Anzahl von Anfragen basierend auf typischen Go-Nutzungsmustern: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ---------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| Anfragen pro 5 Stunden | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | -| Anfragen pro Woche | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | -| Anfragen pro Monat | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ---------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| Anfragen pro 5 Stunden | 880 | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | +| Anfragen pro Woche | 2.150 | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | +| Anfragen pro Monat | 4.300 | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | Die Schätzungen basieren auf beobachteten durchschnittlichen Anfragemustern: -- GLM-5 — 700 Input-, 52.000 Cached-, 150 Output-Tokens pro Anfrage +- GLM-5/5.1 — 700 Input-, 52.000 Cached-, 150 Output-Tokens pro Anfrage - Kimi K2.5 — 870 Input-, 55.000 Cached-, 200 Output-Tokens pro Anfrage - MiniMax M2.7/M2.5 — 300 Input-, 55.000 Cached-, 125 Output-Tokens pro Anfrage - MiMo-V2-Pro — 350 Input-, 41.000 Cached-, 250 Output-Tokens pro Anfrage @@ -114,6 +115,7 @@ Du kannst auf die Go-Modelle auch über die folgenden API-Endpunkte zugreifen. | Modell | Modell-ID | Endpunkt | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/de/keybinds.mdx b/packages/web/src/content/docs/de/keybinds.mdx index 628c65006d..26edf9bdbb 100644 --- a/packages/web/src/content/docs/de/keybinds.mdx +++ b/packages/web/src/content/docs/de/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode verfügt über eine Liste von Tastenkombinationen, die Sie über `tui.j "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/de/zen.mdx b/packages/web/src/content/docs/de/zen.mdx index 0e2481313e..4e94788eec 100644 --- a/packages/web/src/content/docs/de/zen.mdx +++ b/packages/web/src/content/docs/de/zen.mdx @@ -82,6 +82,7 @@ Du kannst auch über die folgenden API-Endpunkte auf unsere Modelle zugreifen. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ Wir unterstützen ein Pay-as-you-go-Modell. Unten findest du die Preise **pro 1M | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/es/go.mdx b/packages/web/src/content/docs/es/go.mdx index 0e91507418..5d38ee9009 100644 --- a/packages/web/src/content/docs/es/go.mdx +++ b/packages/web/src/content/docs/es/go.mdx @@ -64,6 +64,7 @@ Solo un miembro por espacio de trabajo puede suscribirse a OpenCode Go. La lista actual de modelos incluye: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ OpenCode Go incluye los siguientes límites: - **Límite semanal** — $30 de uso - **Límite mensual** — $60 de uso -Los límites se definen en valor en dólares. Esto significa que tu cantidad real de peticiones depende del modelo que uses. Los modelos más económicos como MiniMax M2.5 permiten más peticiones, mientras que los modelos de mayor costo como GLM-5 permiten menos. +Los límites se definen en valor en dólares. Esto significa que tu cantidad real de peticiones depende del modelo que uses. Los modelos más económicos como MiniMax M2.5 permiten más peticiones, mientras que los modelos de mayor costo como GLM-5.1 permiten menos. La siguiente tabla proporciona una cantidad estimada de peticiones basada en los patrones típicos de uso de Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ---------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| peticiones por 5 horas | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| peticiones por semana | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| peticiones por mes | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ---------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| peticiones por 5 horas | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| peticiones por semana | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| peticiones por mes | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | Las estimaciones se basan en los patrones de peticiones promedio observados: -- GLM-5 — 700 tokens de entrada, 52,000 en caché, 150 tokens de salida por petición +- GLM-5/5.1 — 700 tokens de entrada, 52,000 en caché, 150 tokens de salida por petición - Kimi K2.5 — 870 tokens de entrada, 55,000 en caché, 200 tokens de salida por petición - MiniMax M2.7/M2.5 — 300 tokens de entrada, 55,000 en caché, 125 tokens de salida por petición - MiMo-V2-Pro — 350 tokens de entrada, 41,000 en caché, 250 tokens de salida por petición @@ -124,6 +125,7 @@ También puedes acceder a los modelos de Go a través de los siguientes endpoint | Modelo | ID del modelo | Endpoint | Paquete de AI SDK | | ------------ | ------------- | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/es/keybinds.mdx b/packages/web/src/content/docs/es/keybinds.mdx index 4c1f7e1a80..2fc57fa69f 100644 --- a/packages/web/src/content/docs/es/keybinds.mdx +++ b/packages/web/src/content/docs/es/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode tiene una lista de combinaciones de teclas que puede personalizar a tra "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/es/zen.mdx b/packages/web/src/content/docs/es/zen.mdx index 40863cdad5..b6acd296a3 100644 --- a/packages/web/src/content/docs/es/zen.mdx +++ b/packages/web/src/content/docs/es/zen.mdx @@ -91,6 +91,7 @@ También puedes acceder a nuestros modelos a través de los siguientes endpoints | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ Admitimos un modelo de pago por uso. A continuación se muestran los precios **p | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/fr/go.mdx b/packages/web/src/content/docs/fr/go.mdx index 2e72a8485d..2b819438fc 100644 --- a/packages/web/src/content/docs/fr/go.mdx +++ b/packages/web/src/content/docs/fr/go.mdx @@ -54,6 +54,7 @@ Un seul membre par espace de travail peut s'abonner à OpenCode Go. La liste actuelle des modèles comprend : - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go inclut les limites suivantes : - **Limite hebdomadaire** — 30 $ d'utilisation - **Limite mensuelle** — 60 $ d'utilisation -Les limites sont définies en valeur monétaire (dollars). Cela signifie que votre nombre réel de requêtes dépend du modèle que vous utilisez. Les modèles moins chers comme MiniMax M2.5 permettent plus de requêtes, tandis que les modèles plus coûteux comme GLM-5 en permettent moins. +Les limites sont définies en valeur monétaire (dollars). Cela signifie que votre nombre réel de requêtes dépend du modèle que vous utilisez. Les modèles moins chers comme MiniMax M2.5 permettent plus de requêtes, tandis que les modèles plus coûteux comme GLM-5.1 en permettent moins. Le tableau ci-dessous fournit une estimation du nombre de requêtes basée sur des modèles d'utilisation typiques de Go : -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| --------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| requêtes par 5 heures | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| requêtes par semaine | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| requêtes par mois | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| --------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| requêtes par 5 heures | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| requêtes par semaine | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| requêtes par mois | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | Les estimations sont basées sur les modèles de requêtes moyens observés : -- GLM-5 — 700 tokens en entrée, 52,000 en cache, 150 tokens en sortie par requête +- GLM-5/5.1 — 700 tokens en entrée, 52,000 en cache, 150 tokens en sortie par requête - Kimi K2.5 — 870 tokens en entrée, 55,000 en cache, 200 tokens en sortie par requête - MiniMax M2.7/M2.5 — 300 tokens en entrée, 55,000 en cache, 125 tokens en sortie par requête - MiMo-V2-Pro — 350 tokens en entrée, 41,000 en cache, 250 tokens en sortie par requête @@ -112,6 +113,7 @@ Vous pouvez également accéder aux modèles Go via les points de terminaison d' | Modèle | ID de modèle | Point de terminaison | Package AI SDK | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/fr/keybinds.mdx b/packages/web/src/content/docs/fr/keybinds.mdx index 281e5df743..feb4ba37f6 100644 --- a/packages/web/src/content/docs/fr/keybinds.mdx +++ b/packages/web/src/content/docs/fr/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode a une liste de raccourcis clavier que vous pouvez personnaliser via la "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/fr/zen.mdx b/packages/web/src/content/docs/fr/zen.mdx index 00c56ad2f5..f65fcac08a 100644 --- a/packages/web/src/content/docs/fr/zen.mdx +++ b/packages/web/src/content/docs/fr/zen.mdx @@ -82,6 +82,7 @@ Vous pouvez également accéder à nos modèles via les points de terminaison AP | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ Nous prenons en charge un modèle de paiement à l'utilisation. Vous trouverez c | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/go.mdx b/packages/web/src/content/docs/go.mdx index 6bffb65d8c..df65aa76a5 100644 --- a/packages/web/src/content/docs/go.mdx +++ b/packages/web/src/content/docs/go.mdx @@ -64,6 +64,7 @@ Only one member per workspace can subscribe to OpenCode Go. The current list of models includes: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ OpenCode Go includes the following limits: - **Weekly limit** — $30 of usage - **Monthly limit** — $60 of usage -Limits are defined in dollar value. This means your actual request count depends on the model you use. Cheaper models like MiniMax M2.5 allow for more requests, while higher-cost models like GLM-5 allow for fewer. +Limits are defined in dollar value. This means your actual request count depends on the model you use. Cheaper models like MiniMax M2.5 allow for more requests, while higher-cost models like GLM-5.1 allow for fewer. The table below provides an estimated request count based on typical Go usage patterns: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| requests per 5 hour | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| requests per week | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| requests per month | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| requests per 5 hour | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| requests per week | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| requests per month | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | Estimates are based on observed average request patterns: -- GLM-5 — 700 input, 52,000 cached, 150 output tokens per request +- GLM-5/5.1 — 700 input, 52,000 cached, 150 output tokens per request - Kimi K2.5 — 870 input, 55,000 cached, 200 output tokens per request - MiniMax M2.7/M2.5 — 300 input, 55,000 cached, 125 output tokens per request - MiMo-V2-Pro — 350 input, 41,000 cached, 250 output tokens per request @@ -124,6 +125,7 @@ You can also access Go models through the following API endpoints. | Model | Model ID | Endpoint | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/it/go.mdx b/packages/web/src/content/docs/it/go.mdx index 779021a404..e4b95d2286 100644 --- a/packages/web/src/content/docs/it/go.mdx +++ b/packages/web/src/content/docs/it/go.mdx @@ -62,6 +62,7 @@ Solo un membro per workspace può abbonarsi a OpenCode Go. L'elenco attuale dei modelli include: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -80,19 +81,19 @@ OpenCode Go include i seguenti limiti: - **Limite settimanale** — 30 $ di utilizzo - **Limite mensile** — 60 $ di utilizzo -I limiti sono definiti in valore in dollari. Questo significa che il conteggio effettivo delle richieste dipende dal modello utilizzato. Modelli più economici come MiniMax M2.5 consentono più richieste, mentre modelli più costosi come GLM-5 ne consentono di meno. +I limiti sono definiti in valore in dollari. Questo significa che il conteggio effettivo delle richieste dipende dal modello utilizzato. Modelli più economici come MiniMax M2.5 consentono più richieste, mentre modelli più costosi come GLM-5.1 ne consentono di meno. La tabella seguente fornisce una stima del conteggio delle richieste in base a pattern di utilizzo tipici di Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| --------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| richieste ogni 5 ore | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | -| richieste a settimana | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | -| richieste al mese | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| --------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| richieste ogni 5 ore | 880 | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | +| richieste a settimana | 2.150 | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | +| richieste al mese | 4.300 | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | Le stime si basano sui pattern medi di richieste osservati: -- GLM-5 — 700 di input, 52.000 in cache, 150 token di output per richiesta +- GLM-5/5.1 — 700 di input, 52.000 in cache, 150 token di output per richiesta - Kimi K2.5 — 870 di input, 55.000 in cache, 200 token di output per richiesta - MiniMax M2.7/M2.5 — 300 di input, 55.000 in cache, 125 token di output per richiesta - MiMo-V2-Pro — 350 di input, 41.000 in cache, 250 token di output per richiesta @@ -122,6 +123,7 @@ Puoi anche accedere ai modelli Go tramite i seguenti endpoint API. | Modello | ID Modello | Endpoint | Pacchetto AI SDK | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/it/keybinds.mdx b/packages/web/src/content/docs/it/keybinds.mdx index e599f4e417..aef0a4c936 100644 --- a/packages/web/src/content/docs/it/keybinds.mdx +++ b/packages/web/src/content/docs/it/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode ha una lista di scorciatoie che puoi personalizzare tramite `tui.json`. "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/it/zen.mdx b/packages/web/src/content/docs/it/zen.mdx index 8d3ae7f2dc..c099c903c9 100644 --- a/packages/web/src/content/docs/it/zen.mdx +++ b/packages/web/src/content/docs/it/zen.mdx @@ -91,6 +91,7 @@ Puoi anche accedere ai nostri modelli tramite i seguenti endpoint API. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ Supportiamo un modello pay-as-you-go. Qui sotto trovi i prezzi **per 1M token**. | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/ja/go.mdx b/packages/web/src/content/docs/ja/go.mdx index aef6463a3d..35e2775b49 100644 --- a/packages/web/src/content/docs/ja/go.mdx +++ b/packages/web/src/content/docs/ja/go.mdx @@ -54,6 +54,7 @@ OpenCode Goをサブスクライブできるのは、1つのワークスペー 現在のモデルリストには以下が含まれます: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Goには以下の制限が含まれています: - **週間の制限** — 30ドル分の利用 - **月間の制限** — 60ドル分の利用 -制限はドル単位で定義されています。つまり、実際のリクエスト数は使用するモデルによって異なります。MiniMax M2.5のような安価なモデルではより多くのリクエストが可能ですが、GLM-5のような高コストのモデルではリクエスト数が少なくなります。 +制限はドル単位で定義されています。つまり、実際のリクエスト数は使用するモデルによって異なります。MiniMax M2.5のような安価なモデルではより多くのリクエストが可能ですが、GLM-5.1のような高コストのモデルではリクエスト数が少なくなります。 以下の表は、一般的なGoの利用パターンに基づいた推定リクエスト数を示しています: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| 5時間あたりのリクエスト数 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| 週間リクエスト数 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| 月間リクエスト数 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| 5時間あたりのリクエスト数 | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| 週間リクエスト数 | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| 月間リクエスト数 | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | 推定値は、観測された平均的なリクエストパターンに基づいています: -- GLM-5 — リクエストあたり 入力 700トークン、キャッシュ 52,000トークン、出力 150トークン +- GLM-5/5.1 — リクエストあたり 入力 700トークン、キャッシュ 52,000トークン、出力 150トークン - Kimi K2.5 — リクエストあたり 入力 870トークン、キャッシュ 55,000トークン、出力 200トークン - MiniMax M2.7/M2.5 — リクエストあたり 入力 300トークン、キャッシュ 55,000トークン、出力 125トークン - MiMo-V2-Pro — リクエストあたり 入力 350トークン、キャッシュ 41,000トークン、出力 250トークン @@ -112,6 +113,7 @@ Zen残高にクレジットがある場合は、コンソールで**Use balance* | Model | Model ID | Endpoint | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/ja/keybinds.mdx b/packages/web/src/content/docs/ja/keybinds.mdx index 3ec9ca94d5..8d2de3ba95 100644 --- a/packages/web/src/content/docs/ja/keybinds.mdx +++ b/packages/web/src/content/docs/ja/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode には、`tui.json` を通じてカスタマイズできるキーバイ "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/ja/zen.mdx b/packages/web/src/content/docs/ja/zen.mdx index 5e2d68b9ee..93ec6fbec8 100644 --- a/packages/web/src/content/docs/ja/zen.mdx +++ b/packages/web/src/content/docs/ja/zen.mdx @@ -82,6 +82,7 @@ OpenCode Zen は、OpenCode のほかのプロバイダーと同じように動 | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/keybinds.mdx b/packages/web/src/content/docs/keybinds.mdx index 74ef30577e..5488aaf81c 100644 --- a/packages/web/src/content/docs/keybinds.mdx +++ b/packages/web/src/content/docs/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode has a list of keybinds that you can customize through `tui.json`. "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/ko/go.mdx b/packages/web/src/content/docs/ko/go.mdx index 07c47c3143..25d4c27605 100644 --- a/packages/web/src/content/docs/ko/go.mdx +++ b/packages/web/src/content/docs/ko/go.mdx @@ -54,6 +54,7 @@ workspace당 한 명의 멤버만 OpenCode Go를 구독할 수 있습니다. 현재 모델 목록에는 다음이 포함됩니다. - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go에는 다음과 같은 한도가 포함됩니다. - **주간 한도** — 사용량 $30 - **월간 한도** — 사용량 $60 -한도는 달러 금액 기준으로 정의됩니다. 즉, 실제 요청 횟수는 사용하는 모델에 따라 달라집니다. MiniMax M2.5처럼 저렴한 모델은 더 많은 요청이 가능하고, GLM-5처럼 비용이 더 높은 모델은 더 적은 요청이 가능합니다. +한도는 달러 금액 기준으로 정의됩니다. 즉, 실제 요청 횟수는 사용하는 모델에 따라 달라집니다. MiniMax M2.5처럼 저렴한 모델은 더 많은 요청이 가능하고, GLM-5.1처럼 비용이 더 높은 모델은 더 적은 요청이 가능합니다. 아래 표는 일반적인 Go 사용 패턴을 기준으로 한 예상 요청 횟수를 보여줍니다. -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ----------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| 5시간당 요청 횟수 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| 주간 요청 횟수 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| 월간 요청 횟수 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ----------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| 5시간당 요청 횟수 | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| 주간 요청 횟수 | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| 월간 요청 횟수 | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | 예상치는 관찰된 평균 요청 패턴을 기준으로 합니다. -- GLM-5 — 요청당 입력 700, 캐시 52,000, 출력 토큰 150 +- GLM-5/5.1 — 요청당 입력 700, 캐시 52,000, 출력 토큰 150 - Kimi K2.5 — 요청당 입력 870, 캐시 55,000, 출력 토큰 200 - MiniMax M2.7/M2.5 — 요청당 입력 300, 캐시 55,000, 출력 토큰 125 - MiMo-V2-Pro — 요청당 입력 350, 캐시 41,000, 출력 토큰 250 @@ -112,6 +113,7 @@ Zen 잔액에 크레딧도 있다면, console에서 **Use balance** 옵션을 | 모델 | 모델 ID | 엔드포인트 | AI SDK 패키지 | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/ko/keybinds.mdx b/packages/web/src/content/docs/ko/keybinds.mdx index fa8b4e9bdd..b6a605f2eb 100644 --- a/packages/web/src/content/docs/ko/keybinds.mdx +++ b/packages/web/src/content/docs/ko/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode에는 `tui.json`을 통해 커스터마이즈할 수 있는 키바인 "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/ko/zen.mdx b/packages/web/src/content/docs/ko/zen.mdx index 7dc6322202..08f57eaf92 100644 --- a/packages/web/src/content/docs/ko/zen.mdx +++ b/packages/web/src/content/docs/ko/zen.mdx @@ -82,6 +82,7 @@ OpenCode Zen은 OpenCode의 다른 provider와 똑같이 작동합니다. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/nb/go.mdx b/packages/web/src/content/docs/nb/go.mdx index 007655aa57..cdf0c1b460 100644 --- a/packages/web/src/content/docs/nb/go.mdx +++ b/packages/web/src/content/docs/nb/go.mdx @@ -64,6 +64,7 @@ Kun ett medlem per arbeidsområde kan abonnere på OpenCode Go. Den nåværende listen over modeller inkluderer: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ OpenCode Go inkluderer følgende grenser: - **Ukentlig grense** — $30 i bruk - **Månedlig grense** — $60 i bruk -Grensene er definert i dollarverdi. Dette betyr at ditt faktiske antall forespørsler avhenger av modellen du bruker. Billigere modeller som MiniMax M2.5 tillater flere forespørsler, mens dyrere modeller som GLM-5 tillater færre. +Grensene er definert i dollarverdi. Dette betyr at ditt faktiske antall forespørsler avhenger av modellen du bruker. Billigere modeller som MiniMax M2.5 tillater flere forespørsler, mens dyrere modeller som GLM-5.1 tillater færre. Tabellen nedenfor gir et estimert antall forespørsler basert på typiske bruksmønstre for Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------------ | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| forespørsler per 5 timer | 1 150 | 1 850 | 1 290 | 2 150 | 14 000 | 20 000 | -| forespørsler per uke | 2 880 | 4 630 | 3 225 | 5 450 | 35 000 | 50 000 | -| forespørsler per måned | 5 750 | 9 250 | 6 450 | 10 900 | 70 000 | 100 000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------------ | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| forespørsler per 5 timer | 880 | 1 150 | 1 850 | 1 290 | 2 150 | 14 000 | 20 000 | +| forespørsler per uke | 2 150 | 2 880 | 4 630 | 3 225 | 5 450 | 35 000 | 50 000 | +| forespørsler per måned | 4 300 | 5 750 | 9 250 | 6 450 | 10 900 | 70 000 | 100 000 | Estimatene er basert på observerte gjennomsnittlige forespørselsmønstre: -- GLM-5 — 700 input, 52 000 bufret, 150 output-tokens per forespørsel +- GLM-5/5.1 — 700 input, 52 000 bufret, 150 output-tokens per forespørsel - Kimi K2.5 — 870 input, 55 000 bufret, 200 output-tokens per forespørsel - MiniMax M2.7/M2.5 — 300 input, 55 000 bufret, 125 output-tokens per forespørsel - MiMo-V2-Pro — 350 input, 41 000 bufret, 250 output-tokens per forespørsel @@ -124,6 +125,7 @@ Du kan også få tilgang til Go-modeller gjennom følgende API-endepunkter. | Modell | Modell-ID | Endepunkt | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/nb/keybinds.mdx b/packages/web/src/content/docs/nb/keybinds.mdx index f9837480dc..623f7aa241 100644 --- a/packages/web/src/content/docs/nb/keybinds.mdx +++ b/packages/web/src/content/docs/nb/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode har en liste over tastebindinger som du kan tilpasse gjennom `tui.json` "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/nb/zen.mdx b/packages/web/src/content/docs/nb/zen.mdx index 140ce693f9..02ae767b64 100644 --- a/packages/web/src/content/docs/nb/zen.mdx +++ b/packages/web/src/content/docs/nb/zen.mdx @@ -91,6 +91,7 @@ Du kan også få tilgang til modellene våre gjennom følgende API-endepunkter. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ Vi støtter en pay-as-you-go-modell. Nedenfor er prisene **per 1M tokens**. | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/pl/go.mdx b/packages/web/src/content/docs/pl/go.mdx index 78d23659d1..a11a38d3ef 100644 --- a/packages/web/src/content/docs/pl/go.mdx +++ b/packages/web/src/content/docs/pl/go.mdx @@ -58,6 +58,7 @@ Tylko jeden członek na obszar roboczy (workspace) może zasubskrybować OpenCod Obecna lista modeli obejmuje: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -76,19 +77,19 @@ OpenCode Go zawiera następujące limity: - **Limit tygodniowy** — użycie o wartości 30 $ - **Limit miesięczny** — użycie o wartości 60 $ -Limity są zdefiniowane w wartości w dolarach. Oznacza to, że rzeczywista liczba żądań zależy od używanego modelu. Tańsze modele, takie jak MiniMax M2.5, pozwalają na więcej żądań, podczas gdy modele o wyższym koszcie, takie jak GLM-5, pozwalają na mniej. +Limity są zdefiniowane w wartości w dolarach. Oznacza to, że rzeczywista liczba żądań zależy od używanego modelu. Tańsze modele, takie jak MiniMax M2.5, pozwalają na więcej żądań, podczas gdy modele o wyższym koszcie, takie jak GLM-5.1, pozwalają na mniej. Poniższa tabela przedstawia szacunkową liczbę żądań na podstawie typowych wzorców korzystania z Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| żądania na 5 godzin | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| żądania na tydzień | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| żądania na miesiąc | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| żądania na 5 godzin | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| żądania na tydzień | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| żądania na miesiąc | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | Szacunki opierają się na zaobserwowanych średnich wzorcach żądań: -- GLM-5 — 700 tokenów wejściowych, 52 000 w pamięci podręcznej, 150 tokenów wyjściowych na żądanie +- GLM-5/5.1 — 700 tokenów wejściowych, 52 000 w pamięci podręcznej, 150 tokenów wyjściowych na żądanie - Kimi K2.5 — 870 tokenów wejściowych, 55 000 w pamięci podręcznej, 200 tokenów wyjściowych na żądanie - MiniMax M2.7/M2.5 — 300 tokenów wejściowych, 55 000 w pamięci podręcznej, 125 tokenów wyjściowych na żądanie - MiMo-V2-Pro — 350 tokenów wejściowych, 41 000 w pamięci podręcznej, 250 tokenów wyjściowych na żądanie @@ -116,6 +117,7 @@ Możesz również uzyskać dostęp do modeli Go za pośrednictwem następującyc | Model | ID modelu | Punkt końcowy | Pakiet AI SDK | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/pl/keybinds.mdx b/packages/web/src/content/docs/pl/keybinds.mdx index 4744ffc783..0d3068feaf 100644 --- a/packages/web/src/content/docs/pl/keybinds.mdx +++ b/packages/web/src/content/docs/pl/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode zawiera listę skrótów klawiszowych, które można dostosować za pom "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/pl/zen.mdx b/packages/web/src/content/docs/pl/zen.mdx index 360a78a248..98c8b85ef5 100644 --- a/packages/web/src/content/docs/pl/zen.mdx +++ b/packages/web/src/content/docs/pl/zen.mdx @@ -91,6 +91,7 @@ Możesz też uzyskać dostęp do naszych modeli przez poniższe endpointy API. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ Obsługujemy model pay-as-you-go. Poniżej znajdują się ceny **za 1M tokenów* | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/pt-br/go.mdx b/packages/web/src/content/docs/pt-br/go.mdx index 3ad25498ee..ef1827b639 100644 --- a/packages/web/src/content/docs/pt-br/go.mdx +++ b/packages/web/src/content/docs/pt-br/go.mdx @@ -64,6 +64,7 @@ Apenas um membro por workspace pode assinar o OpenCode Go. A lista atual de modelos inclui: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ O OpenCode Go inclui os seguintes limites: - **Limite semanal** — US$ 30 de uso - **Limite mensal** — US$ 60 de uso -Os limites são definidos em valor em dólares. Isso significa que a sua contagem real de requisições depende do modelo que você usa. Modelos mais baratos como o MiniMax M2.5 permitem mais requisições, enquanto modelos de custo mais alto como o GLM-5 permitem menos. +Os limites são definidos em valor em dólares. Isso significa que a sua contagem real de requisições depende do modelo que você usa. Modelos mais baratos como o MiniMax M2.5 permitem mais requisições, enquanto modelos de custo mais alto como o GLM-5.1 permitem menos. A tabela abaixo fornece uma contagem estimada de requisições com base nos padrões típicos de uso do Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ----------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| requisições por 5 horas | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | -| requisições por semana | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | -| requisições por mês | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ----------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| requisições por 5 horas | 880 | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | +| requisições por semana | 2.150 | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | +| requisições por mês | 4.300 | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | As estimativas baseiam-se nos padrões médios de requisições observados: -- GLM-5 — 700 tokens de entrada, 52.000 em cache, 150 tokens de saída por requisição +- GLM-5/5.1 — 700 tokens de entrada, 52.000 em cache, 150 tokens de saída por requisição - Kimi K2.5 — 870 tokens de entrada, 55.000 em cache, 200 tokens de saída por requisição - MiniMax M2.7/M2.5 — 300 tokens de entrada, 55.000 em cache, 125 tokens de saída por requisição - MiMo-V2-Pro — 350 tokens de entrada, 41.000 em cache, 250 tokens de saída por requisição @@ -124,6 +125,7 @@ Você também pode acessar os modelos do Go através dos seguintes endpoints de | Modelo | ID do Modelo | Endpoint | Pacote do AI SDK | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/pt-br/keybinds.mdx b/packages/web/src/content/docs/pt-br/keybinds.mdx index 6c7fcd208e..e1f0f8e7ca 100644 --- a/packages/web/src/content/docs/pt-br/keybinds.mdx +++ b/packages/web/src/content/docs/pt-br/keybinds.mdx @@ -53,6 +53,7 @@ O opencode tem uma lista de atalhos de teclado que você pode personalizar atrav "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/pt-br/zen.mdx b/packages/web/src/content/docs/pt-br/zen.mdx index c57a00cb8d..fd6848df7e 100644 --- a/packages/web/src/content/docs/pt-br/zen.mdx +++ b/packages/web/src/content/docs/pt-br/zen.mdx @@ -82,6 +82,7 @@ Você também pode acessar nossos modelos pelos seguintes endpoints de API. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ Oferecemos um modelo pay-as-you-go. Abaixo estão os preços **por 1M tokens**. | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/ru/go.mdx b/packages/web/src/content/docs/ru/go.mdx index 570bc65d0f..ed74aed731 100644 --- a/packages/web/src/content/docs/ru/go.mdx +++ b/packages/web/src/content/docs/ru/go.mdx @@ -64,6 +64,7 @@ OpenCode Go работает так же, как и любой другой пр Текущий список моделей включает: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -82,19 +83,19 @@ OpenCode Go включает следующие лимиты: - **Недельный лимит** — $30 использования - **Месячный лимит** — $60 использования -Лимиты определены в долларовом эквиваленте. Это означает, что ваше фактическое количество запросов зависит от используемой модели. Более дешевые модели, такие как MiniMax M2.5, позволяют делать больше запросов, в то время как более дорогие, такие как GLM-5, — меньше. +Лимиты определены в долларовом эквиваленте. Это означает, что ваше фактическое количество запросов зависит от используемой модели. Более дешевые модели, такие как MiniMax M2.5, позволяют делать больше запросов, в то время как более дорогие, такие как GLM-5.1, — меньше. В таблице ниже приведено примерное количество запросов на основе типичных сценариев использования Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| запросов за 5 часов | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| запросов в неделю | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| запросов в месяц | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| запросов за 5 часов | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| запросов в неделю | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| запросов в месяц | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | Оценки основаны на наблюдаемых средних показателях запросов: -- GLM-5 — 700 входных, 52,000 кешированных, 150 выходных токенов на запрос +- GLM-5/5.1 — 700 входных, 52,000 кешированных, 150 выходных токенов на запрос - Kimi K2.5 — 870 входных, 55,000 кешированных, 200 выходных токенов на запрос - MiniMax M2.7/M2.5 — 300 входных, 55,000 кешированных, 125 выходных токенов на запрос - MiMo-V2-Pro — 350 входных, 41,000 кешированных, 250 выходных токенов на запрос @@ -124,6 +125,7 @@ OpenCode Go включает следующие лимиты: | Модель | ID модели | Эндпоинт | Пакет AI SDK | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/ru/keybinds.mdx b/packages/web/src/content/docs/ru/keybinds.mdx index bfd4bf0c24..bde4e15530 100644 --- a/packages/web/src/content/docs/ru/keybinds.mdx +++ b/packages/web/src/content/docs/ru/keybinds.mdx @@ -53,6 +53,7 @@ opencode имеет список сочетаний клавиш, которые "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/ru/zen.mdx b/packages/web/src/content/docs/ru/zen.mdx index 9e2adfa63a..7a087d85af 100644 --- a/packages/web/src/content/docs/ru/zen.mdx +++ b/packages/web/src/content/docs/ru/zen.mdx @@ -91,6 +91,7 @@ OpenCode Zen работает как любой другой провайдер | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -128,6 +129,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/th/go.mdx b/packages/web/src/content/docs/th/go.mdx index debdf08d30..b0cf2a8bf8 100644 --- a/packages/web/src/content/docs/th/go.mdx +++ b/packages/web/src/content/docs/th/go.mdx @@ -54,6 +54,7 @@ OpenCode Go ทำงานเหมือนกับผู้ให้บร รายชื่อโมเดลในปัจจุบันประกอบด้วย: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้: - **ขีดจำกัดรายสัปดาห์** — การใช้งานมูลค่า $30 - **ขีดจำกัดรายเดือน** — การใช้งานมูลค่า $60 -ขีดจำกัดถูกกำหนดเป็นมูลค่าดอลลาร์ ซึ่งหมายความว่าจำนวน request จริงของคุณจะขึ้นอยู่กับโมเดลที่คุณใช้งาน โมเดลที่ราคาถูกกว่าอย่าง MiniMax M2.5 จะสามารถส่ง request ได้มากกว่า ในขณะที่โมเดลที่มีราคาสูงกว่าอย่าง GLM-5 จะส่งได้น้อยกว่า +ขีดจำกัดถูกกำหนดเป็นมูลค่าดอลลาร์ ซึ่งหมายความว่าจำนวน request จริงของคุณจะขึ้นอยู่กับโมเดลที่คุณใช้งาน โมเดลที่ราคาถูกกว่าอย่าง MiniMax M2.5 จะสามารถส่ง request ได้มากกว่า ในขณะที่โมเดลที่มีราคาสูงกว่าอย่าง GLM-5.1 จะส่งได้น้อยกว่า ตารางด้านล่างแสดงจำนวน request โดยประมาณตามรูปแบบการใช้งานปกติของ Go: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ---------------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| requests ต่อ 5 ชั่วโมง | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| requests ต่อสัปดาห์ | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| requests ต่อเดือน | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ---------------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| requests ต่อ 5 ชั่วโมง | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| requests ต่อสัปดาห์ | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| requests ต่อเดือน | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | การประมาณการอ้างอิงจากรูปแบบการใช้งาน request โดยเฉลี่ยที่สังเกตพบ: -- GLM-5 — 700 input, 52,000 cached, 150 output tokens ต่อ request +- GLM-5/5.1 — 700 input, 52,000 cached, 150 output tokens ต่อ request - Kimi K2.5 — 870 input, 55,000 cached, 200 output tokens ต่อ request - MiniMax M2.7/M2.5 — 300 input, 55,000 cached, 125 output tokens ต่อ request - MiMo-V2-Pro — 350 input, 41,000 cached, 250 output tokens ต่อ request @@ -112,6 +113,7 @@ OpenCode Go มีขีดจำกัดดังต่อไปนี้: | Model | Model ID | Endpoint | AI SDK Package | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/th/keybinds.mdx b/packages/web/src/content/docs/th/keybinds.mdx index ce3234a04a..2f5bcc5d74 100644 --- a/packages/web/src/content/docs/th/keybinds.mdx +++ b/packages/web/src/content/docs/th/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode มีรายการปุ่มลัดที่คุณปร "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/th/zen.mdx b/packages/web/src/content/docs/th/zen.mdx index ac4261ab1f..cf272576cd 100644 --- a/packages/web/src/content/docs/th/zen.mdx +++ b/packages/web/src/content/docs/th/zen.mdx @@ -84,6 +84,7 @@ OpenCode Zen ทำงานเหมือน provider อื่น ๆ ใน | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -119,6 +120,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/tr/go.mdx b/packages/web/src/content/docs/tr/go.mdx index 067e73ed6a..b7b24b8dec 100644 --- a/packages/web/src/content/docs/tr/go.mdx +++ b/packages/web/src/content/docs/tr/go.mdx @@ -54,6 +54,7 @@ Her çalışma alanından yalnızca bir üye OpenCode Go'ya abone olabilir. Mevcut model listesi şunları içerir: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go aşağıdaki limitleri içerir: - **Haftalık limit** — 30$ kullanım - **Aylık limit** — 60$ kullanım -Limitler dolar değeri üzerinden belirlenmiştir. Bu, gerçek istek sayınızın kullandığınız modele bağlı olduğu anlamına gelir. MiniMax M2.5 gibi daha ucuz modeller daha fazla isteğe izin verirken, GLM-5 gibi yüksek maliyetli modeller daha azına izin verir. +Limitler dolar değeri üzerinden belirlenmiştir. Bu, gerçek istek sayınızın kullandığınız modele bağlı olduğu anlamına gelir. MiniMax M2.5 gibi daha ucuz modeller daha fazla isteğe izin verirken, GLM-5.1 gibi yüksek maliyetli modeller daha azına izin verir. Aşağıdaki tablo, tipik Go kullanım modellerine dayalı tahmini bir istek sayısı sunmaktadır: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| ------------------ | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| 5 saatte bir istek | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | -| haftalık istek | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | -| aylık istek | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| ------------------ | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| 5 saatte bir istek | 880 | 1.150 | 1.850 | 1.290 | 2.150 | 14.000 | 20.000 | +| haftalık istek | 2.150 | 2.880 | 4.630 | 3.225 | 5.450 | 35.000 | 50.000 | +| aylık istek | 4.300 | 5.750 | 9.250 | 6.450 | 10.900 | 70.000 | 100.000 | Tahminler, gözlemlenen ortalama istek modellerine dayanmaktadır: -- GLM-5 — İstek başına 700 girdi, 52.000 önbelleğe alınmış, 150 çıktı token'ı +- GLM-5/5.1 — İstek başına 700 girdi, 52.000 önbelleğe alınmış, 150 çıktı token'ı - Kimi K2.5 — İstek başına 870 girdi, 55.000 önbelleğe alınmış, 200 çıktı token'ı - MiniMax M2.7/M2.5 — İstek başına 300 girdi, 55.000 önbelleğe alınmış, 125 çıktı token'ı - MiMo-V2-Pro — İstek başına 350 girdi, 41.000 önbelleğe alınmış, 250 çıktı token'ı @@ -112,6 +113,7 @@ Go modellerine aşağıdaki API uç noktaları aracılığıyla da erişebilirsi | Model | Model ID | Uç Nokta | AI SDK Paketi | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/tr/keybinds.mdx b/packages/web/src/content/docs/tr/keybinds.mdx index 7d3142bf38..bbf8c3bfa9 100644 --- a/packages/web/src/content/docs/tr/keybinds.mdx +++ b/packages/web/src/content/docs/tr/keybinds.mdx @@ -53,6 +53,7 @@ opencode, `tui.json` aracılığıyla özelleştirebileceğiniz bir tuş bağlan "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/tr/zen.mdx b/packages/web/src/content/docs/tr/zen.mdx index dc3a5f3dbf..89276dd4c5 100644 --- a/packages/web/src/content/docs/tr/zen.mdx +++ b/packages/web/src/content/docs/tr/zen.mdx @@ -82,6 +82,7 @@ Modellerimize aşağıdaki API uç noktaları aracılığıyla da erişebilirsin | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ Kullandıkça öde modelini destekliyoruz. Aşağıda **1M token başına** fiya | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/zen.mdx b/packages/web/src/content/docs/zen.mdx index c16fc5270e..f16ec6f715 100644 --- a/packages/web/src/content/docs/zen.mdx +++ b/packages/web/src/content/docs/zen.mdx @@ -91,6 +91,7 @@ You can also access our models through the following API endpoints. | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -124,6 +125,7 @@ We support a pay-as-you-go model. Below are the prices **per 1M tokens**. | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/zh-cn/go.mdx b/packages/web/src/content/docs/zh-cn/go.mdx index ed7d39f754..7b1a3b77fc 100644 --- a/packages/web/src/content/docs/zh-cn/go.mdx +++ b/packages/web/src/content/docs/zh-cn/go.mdx @@ -54,6 +54,7 @@ OpenCode Go 的工作方式与 OpenCode 中的其他提供商一样。 当前支持的模型列表包括: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go 包含以下限制: - **每周限制** — 30 美元使用额度 - **每月限制** — 60 美元使用额度 -限制以美元价值定义。这意味着你的实际请求数取决于你所使用的模型。较便宜的模型(如 MiniMax M2.5)允许更多请求,而较高成本的模型(如 GLM-5)允许较少请求。 +限制以美元价值定义。这意味着你的实际请求数取决于你所使用的模型。较便宜的模型(如 MiniMax M2.5)允许更多请求,而较高成本的模型(如 GLM-5.1)允许较少请求。 下表提供了基于典型 Go 使用模式的预估请求数: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| --------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| 每 5 小时请求数 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| 每周请求数 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| 每月请求数 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| --------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| 每 5 小时请求数 | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| 每周请求数 | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| 每月请求数 | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | 预估值基于观察到的平均请求模式: -- GLM-5 — 每次请求 700 个输入 token,52,000 个缓存 token,150 个输出 token +- GLM-5/5.1 — 每次请求 700 个输入 token,52,000 个缓存 token,150 个输出 token - Kimi K2.5 — 每次请求 870 个输入 token,55,000 个缓存 token,200 个输出 token - MiMo-V2-Pro — 每次请求 350 个输入 token,41,000 个缓存 token,250 个输出 token - MiMo-V2-Omni — 每次请求 1000 个输入 token,60,000 个缓存 token,140 个输出 token @@ -112,6 +113,7 @@ OpenCode Go 包含以下限制: | 模型 | 模型 ID | 端点 | AI SDK 包 | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/zh-cn/keybinds.mdx b/packages/web/src/content/docs/zh-cn/keybinds.mdx index 33f75c6dc8..0989a30f57 100644 --- a/packages/web/src/content/docs/zh-cn/keybinds.mdx +++ b/packages/web/src/content/docs/zh-cn/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode 提供了一系列快捷键,您可以通过 `tui.json` 进行自定 "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/zh-cn/zen.mdx b/packages/web/src/content/docs/zh-cn/zen.mdx index b73c8c6ccb..5df3609543 100644 --- a/packages/web/src/content/docs/zh-cn/zen.mdx +++ b/packages/web/src/content/docs/zh-cn/zen.mdx @@ -82,6 +82,7 @@ OpenCode Zen 的工作方式与 OpenCode 中的任何其他提供商相同。 | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -117,6 +118,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/packages/web/src/content/docs/zh-tw/go.mdx b/packages/web/src/content/docs/zh-tw/go.mdx index 74245b669c..b6b76afffc 100644 --- a/packages/web/src/content/docs/zh-tw/go.mdx +++ b/packages/web/src/content/docs/zh-tw/go.mdx @@ -54,6 +54,7 @@ OpenCode Go 的運作方式與 OpenCode 中的任何其他供應商相同。 目前的模型清單包括: - **GLM-5** +- **GLM-5.1** - **Kimi K2.5** - **MiMo-V2-Pro** - **MiMo-V2-Omni** @@ -72,19 +73,19 @@ OpenCode Go 包含以下限制: - **每週限制** — $30 美元的使用量 - **每月限制** — $60 美元的使用量 -限制是以美元價值來定義。這意味著您的實際請求次數取決於您使用的模型。像 MiniMax M2.5 這樣較便宜的模型允許更多的請求次數,而像 GLM-5 這樣成本較高的模型則允許較少次數。 +限制是以美元價值來定義。這意味著您的實際請求次數取決於您使用的模型。像 MiniMax M2.5 這樣較便宜的模型允許更多的請求次數,而像 GLM-5.1 這樣成本較高的模型則允許較少次數。 下表提供了基於典型 Go 使用模式的預估請求次數: -| | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | -| --------------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | -| 每 5 小時請求數 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | -| 每週請求數 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | -| 每月請求數 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | +| | GLM-5.1 | GLM-5 | Kimi K2.5 | MiMo-V2-Pro | MiMo-V2-Omni | MiniMax M2.7 | MiniMax M2.5 | +| --------------- | ------- | ----- | --------- | ----------- | ------------ | ------------ | ------------ | +| 每 5 小時請求數 | 880 | 1,150 | 1,850 | 1,290 | 2,150 | 14,000 | 20,000 | +| 每週請求數 | 2,150 | 2,880 | 4,630 | 3,225 | 5,450 | 35,000 | 50,000 | +| 每月請求數 | 4,300 | 5,750 | 9,250 | 6,450 | 10,900 | 70,000 | 100,000 | 預估值是基於觀察到的平均請求模式: -- GLM-5 — 每次請求 700 個輸入 token、52,000 個快取 token、150 個輸出 token +- GLM-5/5.1 — 每次請求 700 個輸入 token、52,000 個快取 token、150 個輸出 token - Kimi K2.5 — 每次請求 870 個輸入 token、55,000 個快取 token、200 個輸出 token - MiniMax M2.7/M2.5 — 每次請求 300 個輸入 token、55,000 個快取 token、125 個輸出 token - MiMo-V2-Pro — 每次請求 350 個輸入 token、41,000 個快取 token、250 個輸出 token @@ -112,6 +113,7 @@ OpenCode Go 包含以下限制: | 模型 | 模型 ID | 端點 | AI SDK 套件 | | ------------ | ------------ | ------------------------------------------------ | --------------------------- | +| GLM-5.1 | glm-5.1 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM-5 | glm-5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiMo-V2-Pro | mimo-v2-pro | `https://opencode.ai/zen/go/v1/chat/completions` | `@ai-sdk/openai-compatible` | diff --git a/packages/web/src/content/docs/zh-tw/keybinds.mdx b/packages/web/src/content/docs/zh-tw/keybinds.mdx index 574404b2fd..61d902141a 100644 --- a/packages/web/src/content/docs/zh-tw/keybinds.mdx +++ b/packages/web/src/content/docs/zh-tw/keybinds.mdx @@ -53,6 +53,7 @@ OpenCode 提供了一系列快捷鍵,您可以透過 `tui.json` 進行自訂 "model_cycle_favorite": "none", "model_cycle_favorite_reverse": "none", "variant_cycle": "ctrl+t", + "variant_list": "none", "command_list": "ctrl+p", "agent_list": "a", "agent_cycle": "tab", diff --git a/packages/web/src/content/docs/zh-tw/zen.mdx b/packages/web/src/content/docs/zh-tw/zen.mdx index 674458030f..1b2beb2c13 100644 --- a/packages/web/src/content/docs/zh-tw/zen.mdx +++ b/packages/web/src/content/docs/zh-tw/zen.mdx @@ -86,6 +86,7 @@ OpenCode Zen 的運作方式和 OpenCode 中的其他供應商一樣。 | Gemini 3 Flash | gemini-3-flash | `https://opencode.ai/zen/v1/models/gemini-3-flash` | `@ai-sdk/google` | | MiniMax M2.5 | minimax-m2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | MiniMax M2.5 Free | minimax-m2.5-free | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | +| GLM 5.1 | glm-5.1 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | GLM 5 | glm-5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Kimi K2.5 | kimi-k2.5 | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | | Big Pickle | big-pickle | `https://opencode.ai/zen/v1/chat/completions` | `@ai-sdk/openai-compatible` | @@ -122,6 +123,7 @@ https://opencode.ai/zen/v1/models | Nemotron 3 Super Free | Free | Free | Free | - | | MiniMax M2.5 Free | Free | Free | Free | - | | MiniMax M2.5 | $0.30 | $1.20 | $0.06 | $0.375 | +| GLM 5.1 | $1.40 | $4.40 | $0.26 | - | | GLM 5 | $1.00 | $3.20 | $0.20 | - | | Kimi K2.5 | $0.60 | $3.00 | $0.10 | - | | Qwen3 Coder 480B | $0.45 | $1.50 | - | - | diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 3d3f94a819..2004bd733f 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.3.17", + "version": "1.4.0", "publisher": "sst-dev", "repository": { "type": "git",