From 228e9095ba3988a02664c3816cb51f98584e86c2 Mon Sep 17 00:00:00 2001 From: Matthew Feroz <136640686+MatthewFeroz@users.noreply.github.com> Date: Mon, 14 Sep 2026 03:16:48 -0400 Subject: [PATCH 01/14] fix(ui): add Merge Gateway logo (#42015) --- packages/ui/src/assets/icons/provider/merge-gateway.svg | 4 ++++ packages/ui/src/components/provider-icons/sprite.svg | 8 ++++++++ packages/ui/src/components/provider-icons/types.ts | 1 + 3 files changed, 13 insertions(+) create mode 100644 packages/ui/src/assets/icons/provider/merge-gateway.svg diff --git a/packages/ui/src/assets/icons/provider/merge-gateway.svg b/packages/ui/src/assets/icons/provider/merge-gateway.svg new file mode 100644 index 000000000000..a219b55bf965 --- /dev/null +++ b/packages/ui/src/assets/icons/provider/merge-gateway.svg @@ -0,0 +1,4 @@ + + + + diff --git a/packages/ui/src/components/provider-icons/sprite.svg b/packages/ui/src/components/provider-icons/sprite.svg index c8099d7ad1ba..392226323400 100644 --- a/packages/ui/src/components/provider-icons/sprite.svg +++ b/packages/ui/src/components/provider-icons/sprite.svg @@ -576,6 +576,14 @@ stroke-linejoin="round" > + + + + Date: Mon, 14 Sep 2026 12:08:40 -0500 Subject: [PATCH 02/14] test(app): retire legacy layout e2e coverage (#49015) Co-authored-by: rekram1-node --- .../e2e/regression/legacy-new-session.spec.ts | 41 ------------------- .../session-timeline-projection.spec.ts | 8 +--- 2 files changed, 2 insertions(+), 47 deletions(-) delete mode 100644 packages/app/e2e/regression/legacy-new-session.spec.ts diff --git a/packages/app/e2e/regression/legacy-new-session.spec.ts b/packages/app/e2e/regression/legacy-new-session.spec.ts deleted file mode 100644 index 45cd64adcc69..000000000000 --- a/packages/app/e2e/regression/legacy-new-session.spec.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { expect, test } from "@playwright/test" -import { base64Encode } from "@opencode-ai/core/util/encode" -import { mockOpenCodeServer } from "../utils/mock-server" - -const draftID = "draft_legacy_new_session" -const directory = "C:/OpenCode/LegacyNewSession" -const server = `http://${process.env.PLAYWRIGHT_SERVER_HOST ?? "127.0.0.1"}:${process.env.PLAYWRIGHT_SERVER_PORT ?? "4096"}` - -test("redirects a draft to the legacy new-session route", async ({ page }) => { - await mockOpenCodeServer(page, { - directory, - project: { - id: "proj_legacy_new_session", - worktree: directory, - vcs: "git", - name: "legacy-new-session", - time: { created: 1700000000000, updated: 1700000000000 }, - sandboxes: [], - }, - provider: { all: [], connected: [], default: {} }, - sessions: [], - pageMessages: () => ({ items: [] }), - }) - await page.addInitScript( - ({ directory, draftID, server }) => { - localStorage.setItem("settings.v3", JSON.stringify({ general: { newLayoutDesigns: false } })) - localStorage.setItem("app-version.v1", JSON.stringify({ version: "1.17.20" })) - localStorage.setItem( - "opencode.window.browser.dat:tabs", - JSON.stringify([{ type: "draft", draftID, server, directory }]), - ) - }, - { directory, draftID, server }, - ) - - await page.goto(`/new-session?draftId=${draftID}`) - - await expect(page).toHaveURL(`/${base64Encode(directory)}/session`) - await expect(page.locator("header[data-tauri-drag-region]")).toBeVisible() - await expect(page.locator('[data-component="prompt-input"]')).toBeVisible() -}) diff --git a/packages/app/e2e/regression/session-timeline-projection.spec.ts b/packages/app/e2e/regression/session-timeline-projection.spec.ts index b1aabcc32ca9..54c84a2bea5d 100644 --- a/packages/app/e2e/regression/session-timeline-projection.spec.ts +++ b/packages/app/e2e/regression/session-timeline-projection.spec.ts @@ -128,7 +128,7 @@ test.describe("session timeline projection", () => { await expect(page.locator('[data-timeline-row="TurnGap"]')).toBeVisible() }) - test("renders comment strips and historical diff summary overflow", async ({ page }) => { + test("renders inline comments and historical diff summary overflow", async ({ page }) => { const user = userMessage( [ userText("The user made the following comment regarding lines 4 through 8 of src/a.ts: Keep this stable", { @@ -152,14 +152,10 @@ test.describe("session timeline projection", () => { parentID: "msg_2000_diff_next_user", created: 1700000011000, }) - await setupTimeline(page, { - messages: [user, assistantMessage(), nextUser, nextAssistant], - settings: { newLayoutDesigns: false }, - }) + await setupTimeline(page, { messages: [user, assistantMessage(), nextUser, nextAssistant] }) const scroller = page.locator(".scroll-view__viewport", { has: page.locator("[data-timeline-row]") }) await scroller.evaluate((element) => (element.scrollTop = 0)) - await expect(page.locator('[data-timeline-row="CommentStrip"]')).toBeVisible() await expect(page.getByText("Keep this stable", { exact: true })).toBeVisible() await expect(page.locator('[data-timeline-row="DiffSummary"]')).toBeVisible() await expect(page.getByText(/show all/i)).toBeVisible() From a97622c801f4ca571530ddc51076af659a9c32cd Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" <219766164+opencode-agent[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 13:24:08 -0400 Subject: [PATCH 03/14] fix(tui): surface remote auth startup errors (#49016) Co-authored-by: thdxr <826656+thdxr@users.noreply.github.com> --- packages/opencode/src/cli/cmd/tui.ts | 2 +- .../instance/httpapi/middleware/error.ts | 3 +- .../server/httpapi-error-middleware.test.ts | 21 +++++++ packages/tui/src/app.tsx | 4 +- packages/tui/src/util/error.ts | 11 ++++ packages/tui/test/app-lifecycle.test.tsx | 62 +++++++++++++++++++ 6 files changed, 100 insertions(+), 3 deletions(-) diff --git a/packages/opencode/src/cli/cmd/tui.ts b/packages/opencode/src/cli/cmd/tui.ts index 95ffac7ea51d..d5fa46bfb115 100644 --- a/packages/opencode/src/cli/cmd/tui.ts +++ b/packages/opencode/src/cli/cmd/tui.ts @@ -303,7 +303,7 @@ export const TuiThreadCommand = cmd({ unguard?.() } catch {} } - process.exit(0) + process.exit() }, }) // scratch diff --git a/packages/opencode/src/server/routes/instance/httpapi/middleware/error.ts b/packages/opencode/src/server/routes/instance/httpapi/middleware/error.ts index 21b53aba7567..3bedd1970441 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/middleware/error.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/middleware/error.ts @@ -20,7 +20,8 @@ export const errorLayer = HttpRouter.middleware<{ handles: unknown }>()((effect) ConfigErrorV1.JsonError.isInstance(error) || ConfigErrorV1.InvalidError.isInstance(error) || ConfigErrorV1.FrontmatterError.isInstance(error) || - ConfigErrorV1.DirectoryTypoError.isInstance(error) + ConfigErrorV1.DirectoryTypoError.isInstance(error) || + ConfigErrorV1.RemoteAuthError.isInstance(error) ) { return Effect.succeed(HttpServerResponse.jsonUnsafe(error.toObject(), { status: 400 })) } diff --git a/packages/opencode/test/server/httpapi-error-middleware.test.ts b/packages/opencode/test/server/httpapi-error-middleware.test.ts index 7bfc6da032f6..525bf34e205f 100644 --- a/packages/opencode/test/server/httpapi-error-middleware.test.ts +++ b/packages/opencode/test/server/httpapi-error-middleware.test.ts @@ -83,6 +83,27 @@ describe("HttpApi error middleware", () => { }), ) + it.live("returns remote auth defects as structured client errors", () => + Effect.gen(function* () { + const configError = new ConfigErrorV1.RemoteAuthError({ + url: "https://example.com", + remote: "https://config.example.com/opencode.json", + }) + + yield* HttpRouter.add("GET", "/remote-auth-error", Effect.die(configError)).pipe( + Layer.provide(errorLayer), + HttpRouter.serve, + Layer.build, + ) + + const response = yield* HttpClientRequest.get("/remote-auth-error").pipe(HttpClient.execute) + const body = yield* response.json + + expect(response.status).toBe(400) + expect(body).toEqual(configError.toObject()) + }), + ) + it.live("does not map storage not-found defects to 404", () => Effect.gen(function* () { yield* HttpRouter.add( diff --git a/packages/tui/src/app.tsx b/packages/tui/src/app.tsx index 3f1da522bb06..6852311f9e84 100644 --- a/packages/tui/src/app.tsx +++ b/packages/tui/src/app.tsx @@ -356,8 +356,10 @@ export const run = Effect.fn("Tui.run")(function* (input: TuiInput) { ) yield* Effect.sync(() => { win32FlushInputBuffer() - if (result.reason !== undefined) + if (result.reason !== undefined) { process.stderr.write((cliErrorMessage(result.reason) ?? errorFormat(result.reason)) + "\n") + process.exitCode = 1 + } if (result.epilogue) process.stdout.write(result.epilogue + "\n") }) }) diff --git a/packages/tui/src/util/error.ts b/packages/tui/src/util/error.ts index 757758a2058d..606bfb3bb71f 100644 --- a/packages/tui/src/util/error.ts +++ b/packages/tui/src/util/error.ts @@ -47,6 +47,17 @@ export function cliErrorMessage(input: unknown): string | undefined { const frontmatter = configData(input, "ConfigFrontmatterError") if (frontmatter) return field(frontmatter, "message") ?? "" + const remoteAuth = configData(input, "ConfigRemoteAuthError") + if (remoteAuth) { + const url = field(remoteAuth, "url") + const remote = field(remoteAuth, "remote") + return [ + `Failed to load remote config${remote ? ` from ${remote}` : ""}: the server returned a login page instead of JSON.`, + "Authentication is missing or has expired (the endpoint is likely behind an SSO or identity-aware proxy).", + ...(url ? [`Run \`opencode auth login ${url}\` to re-authenticate.`] : []), + ].join("\n") + } + const invalid = configData(input, "ConfigInvalidError") if (invalid) { const path = field(invalid, "path") diff --git a/packages/tui/test/app-lifecycle.test.tsx b/packages/tui/test/app-lifecycle.test.tsx index 570663424718..8cd40315ccc5 100644 --- a/packages/tui/test/app-lifecycle.test.tsx +++ b/packages/tui/test/app-lifecycle.test.tsx @@ -126,3 +126,65 @@ test("app.exit prints the session epilogue after scoped cleanup", async () => { mock.restore() } }) + +test("fatal startup errors set a nonzero exit after scoped cleanup", async () => { + const setup = await createTestRenderer({ width: 80, height: 24, useThread: false }) + const core = await import("@opentui/core") + await mock.module("@opentui/core", () => ({ ...core, createCliRenderer: async () => setup.renderer })) + const events = createEventSource() + const calls = createFetch((url) => { + if (url.pathname === "/config") + return json( + { + name: "ConfigRemoteAuthError", + data: { + url: "https://example.com", + remote: "https://config.example.com/opencode.json", + }, + }, + { status: 400 }, + ) + return undefined + }) + let disposes = 0 + const originalWrite = process.stderr.write.bind(process.stderr) + const originalExitCode = process.exitCode ?? 0 + let stderr = "" + + process.stderr.write = ((chunk: string | Uint8Array) => { + stderr += String(chunk) + return true + }) as typeof process.stderr.write + + try { + const { run } = await import("../src/app") + const task = Effect.runPromise( + run({ + url: "http://test", + directory, + config: createTuiResolvedConfig({ plugin_enabled: {} }), + fetch: calls.fetch, + events: events.source, + args: {}, + pluginHost: { + async start() {}, + async dispose() { + disposes++ + }, + }, + }).pipe(Effect.provide(AppNodeBuilder.build(Global.node))), + ) + + await task + expect(stderr).toContain("Run `opencode auth login https://example.com` to re-authenticate.") + expect(stderr).not.toContain("Unexpected server error") + expect(process.exitCode).toBe(1) + expect(setup.renderer.isDestroyed).toBe(true) + expect(disposes).toBe(1) + } finally { + process.stderr.write = originalWrite + process.exitCode = originalExitCode + if (!setup.renderer.isDestroyed) setup.renderer.destroy() + mock.restore() + } +}) From a74c472ffb941e6b027e5348be50cfe2225c6c56 Mon Sep 17 00:00:00 2001 From: opencode Date: Mon, 14 Sep 2026 17:47:27 +0000 Subject: [PATCH 04/14] sync release versions for v1.18.31 --- bun.lock | 56 ++++++++++----------- packages/app/package.json | 2 +- packages/cli/package.json | 2 +- packages/codemode/package.json | 2 +- packages/console/app/package.json | 2 +- packages/console/core/package.json | 2 +- packages/console/function/package.json | 2 +- packages/console/mail/package.json | 2 +- packages/console/support/package.json | 2 +- packages/core/package.json | 2 +- packages/desktop/package.json | 2 +- packages/effect-drizzle-sqlite/package.json | 2 +- packages/effect-sqlite-node/package.json | 2 +- packages/enterprise/package.json | 2 +- packages/function/package.json | 2 +- packages/http-recorder/package.json | 2 +- packages/llm/package.json | 2 +- packages/opencode/package.json | 2 +- packages/plugin/package.json | 2 +- packages/sdk/js/package.json | 2 +- packages/server/package.json | 2 +- packages/session-ui/package.json | 2 +- packages/slack/package.json | 2 +- packages/stats/app/package.json | 2 +- packages/stats/core/package.json | 2 +- packages/stats/server/package.json | 2 +- packages/tui/package.json | 2 +- packages/ui/package.json | 2 +- packages/web/package.json | 2 +- sdks/vscode/package.json | 2 +- 30 files changed, 57 insertions(+), 57 deletions(-) diff --git a/bun.lock b/bun.lock index a8774d3aa2bd..338f7f02342e 100644 --- a/bun.lock +++ b/bun.lock @@ -29,7 +29,7 @@ }, "packages/app": { "name": "@opencode-ai/app", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@corvu/drawer": "catalog:", "@dnd-kit/abstract": "0.5.0", @@ -96,7 +96,7 @@ }, "packages/cli": { "name": "@opencode-ai/cli", - "version": "1.18.30", + "version": "1.18.31", "bin": { "lildax": "./bin/lildax.cjs", }, @@ -144,7 +144,7 @@ }, "packages/codemode": { "name": "@opencode-ai/codemode", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "acorn": "8.15.0", "effect": "catalog:", @@ -158,7 +158,7 @@ }, "packages/console/app": { "name": "@opencode-ai/console-app", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@ibm/plex": "6.4.1", @@ -195,7 +195,7 @@ }, "packages/console/core": { "name": "@opencode-ai/console-core", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@aws-sdk/client-sts": "3.782.0", "@jsx-email/render": "1.1.1", @@ -222,7 +222,7 @@ }, "packages/console/function": { "name": "@opencode-ai/console-function", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@ai-sdk/anthropic": "3.0.82", "@ai-sdk/openai": "3.0.48", @@ -245,7 +245,7 @@ }, "packages/console/mail": { "name": "@opencode-ai/console-mail", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", @@ -269,7 +269,7 @@ }, "packages/console/support": { "name": "@opencode-ai/console-support", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@cloudflare/vite-plugin": "1.15.2", "@opencode-ai/console-core": "workspace:*", @@ -289,7 +289,7 @@ }, "packages/core": { "name": "@opencode-ai/core", - "version": "1.18.30", + "version": "1.18.31", "bin": { "opencode": "./bin/opencode", }, @@ -383,7 +383,7 @@ }, "packages/desktop": { "name": "@opencode-ai/desktop", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@zip.js/zip.js": "2.7.62", "drizzle-orm": "catalog:", @@ -437,7 +437,7 @@ }, "packages/effect-drizzle-sqlite": { "name": "@opencode-ai/effect-drizzle-sqlite", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "drizzle-orm": "catalog:", "effect": "catalog:", @@ -451,7 +451,7 @@ }, "packages/effect-sqlite-node": { "name": "@opencode-ai/effect-sqlite-node", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "effect": "catalog:", }, @@ -463,7 +463,7 @@ }, "packages/enterprise": { "name": "@opencode-ai/enterprise", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@hono/standard-validator": "catalog:", "@opencode-ai/core": "workspace:*", @@ -495,7 +495,7 @@ }, "packages/function": { "name": "@opencode-ai/function", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@octokit/auth-app": "8.0.1", "@octokit/rest": "catalog:", @@ -511,7 +511,7 @@ }, "packages/http-recorder": { "name": "@opencode-ai/http-recorder", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@effect/platform-node": "4.0.0-beta.83", "@effect/platform-node-shared": "4.0.0-beta.83", @@ -542,7 +542,7 @@ }, "packages/llm": { "name": "@opencode-ai/llm", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@opencode-ai/schema": "workspace:*", "@smithy/eventstream-codec": "4.2.14", @@ -561,7 +561,7 @@ }, "packages/opencode": { "name": "opencode", - "version": "1.18.30", + "version": "1.18.31", "bin": { "opencode": "./bin/opencode", }, @@ -692,7 +692,7 @@ }, "packages/plugin": { "name": "@opencode-ai/plugin", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@ai-sdk/provider": "3.0.8", "@opencode-ai/sdk": "workspace:*", @@ -768,7 +768,7 @@ }, "packages/sdk/js": { "name": "@opencode-ai/sdk", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "cross-spawn": "catalog:", }, @@ -783,7 +783,7 @@ }, "packages/server": { "name": "@opencode-ai/server", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/protocol": "workspace:*", @@ -798,7 +798,7 @@ }, "packages/session-ui": { "name": "@opencode-ai/session-ui", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@kobalte/core": "catalog:", "@opencode-ai/client": "file:../app/vendor/opencode-ai-client-1.17.13-v2.tgz", @@ -838,7 +838,7 @@ }, "packages/slack": { "name": "@opencode-ai/slack", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@opencode-ai/sdk": "workspace:*", "@slack/bolt": "^3.17.1", @@ -851,7 +851,7 @@ }, "packages/stats/app": { "name": "@opencode-ai/stats-app", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@ibm/plex": "6.4.1", "@kobalte/core": "catalog:", @@ -878,7 +878,7 @@ }, "packages/stats/core": { "name": "@opencode-ai/stats-core", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@aws-sdk/client-athena": "3.933.0", "@planetscale/database": "1.19.0", @@ -897,7 +897,7 @@ }, "packages/stats/server": { "name": "@opencode-ai/stats-server", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@aws-sdk/client-firehose": "3.933.0", "@effect/platform-node": "catalog:", @@ -939,7 +939,7 @@ }, "packages/tui": { "name": "@opencode-ai/tui", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@opencode-ai/core": "workspace:*", "@opencode-ai/plugin": "workspace:*", @@ -966,7 +966,7 @@ }, "packages/ui": { "name": "@opencode-ai/ui", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@kobalte/core": "catalog:", "@pierre/diffs": "catalog:", @@ -1017,7 +1017,7 @@ }, "packages/web": { "name": "@opencode-ai/web", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@astrojs/cloudflare": "12.6.3", "@astrojs/markdown-remark": "6.3.1", diff --git a/packages/app/package.json b/packages/app/package.json index 17b356ed6087..97c98e9fc3f2 100644 --- a/packages/app/package.json +++ b/packages/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/app", - "version": "1.18.30", + "version": "1.18.31", "description": "", "type": "module", "exports": { diff --git a/packages/cli/package.json b/packages/cli/package.json index f6dd6bf831f3..7e94b2310840 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/cli", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "bin": { diff --git a/packages/codemode/package.json b/packages/codemode/package.json index c516b3a98589..8a14b5769d16 100644 --- a/packages/codemode/package.json +++ b/packages/codemode/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/codemode", - "version": "1.18.30", + "version": "1.18.31", "description": "Effect-native confined code execution over schema-described tools", "private": true, "type": "module", diff --git a/packages/console/app/package.json b/packages/console/app/package.json index 3651594fd764..b89e19a72ba2 100644 --- a/packages/console/app/package.json +++ b/packages/console/app/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-app", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/console/core/package.json b/packages/console/core/package.json index 19aade616d72..fefbe8abfd8b 100644 --- a/packages/console/core/package.json +++ b/packages/console/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/console-core", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/console/function/package.json b/packages/console/function/package.json index d77be8cb6a5f..1026754e6367 100644 --- a/packages/console/function/package.json +++ b/packages/console/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-function", - "version": "1.18.30", + "version": "1.18.31", "$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 e35574b3e9b9..755102b6e74f 100644 --- a/packages/console/mail/package.json +++ b/packages/console/mail/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-mail", - "version": "1.18.30", + "version": "1.18.31", "dependencies": { "@jsx-email/all": "2.2.3", "@jsx-email/cli": "1.4.3", diff --git a/packages/console/support/package.json b/packages/console/support/package.json index 75e8e0714716..56a0099ad40f 100644 --- a/packages/console/support/package.json +++ b/packages/console/support/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/console-support", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/core/package.json b/packages/core/package.json index ab20288b52a9..2b465e5852fd 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.18.30", + "version": "1.18.31", "name": "@opencode-ai/core", "type": "module", "license": "MIT", diff --git a/packages/desktop/package.json b/packages/desktop/package.json index 7c55897b748a..f494e5341673 100644 --- a/packages/desktop/package.json +++ b/packages/desktop/package.json @@ -1,7 +1,7 @@ { "name": "@opencode-ai/desktop", "private": true, - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "homepage": "https://opencode.ai", diff --git a/packages/effect-drizzle-sqlite/package.json b/packages/effect-drizzle-sqlite/package.json index 35cc50f97d47..1dc5d0ce6653 100644 --- a/packages/effect-drizzle-sqlite/package.json +++ b/packages/effect-drizzle-sqlite/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.18.30", + "version": "1.18.31", "name": "@opencode-ai/effect-drizzle-sqlite", "type": "module", "license": "MIT", diff --git a/packages/effect-sqlite-node/package.json b/packages/effect-sqlite-node/package.json index 19d0652c1a65..5a425b9feb74 100644 --- a/packages/effect-sqlite-node/package.json +++ b/packages/effect-sqlite-node/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.18.30", + "version": "1.18.31", "name": "@opencode-ai/effect-sqlite-node", "type": "module", "license": "MIT", diff --git a/packages/enterprise/package.json b/packages/enterprise/package.json index 9d61ae5eacfd..aea997e34e2a 100644 --- a/packages/enterprise/package.json +++ b/packages/enterprise/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/enterprise", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/function/package.json b/packages/function/package.json index 7d9bc6548b66..03348052a2fd 100644 --- a/packages/function/package.json +++ b/packages/function/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/function", - "version": "1.18.30", + "version": "1.18.31", "$schema": "https://json.schemastore.org/package.json", "private": true, "type": "module", diff --git a/packages/http-recorder/package.json b/packages/http-recorder/package.json index cc8ae63655f9..1fd0b834ebab 100644 --- a/packages/http-recorder/package.json +++ b/packages/http-recorder/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.18.30", + "version": "1.18.31", "name": "@opencode-ai/http-recorder", "description": "Record and replay Effect HTTP client traffic with deterministic cassettes", "type": "module", diff --git a/packages/llm/package.json b/packages/llm/package.json index 79471820d654..2b10849540a0 100644 --- a/packages/llm/package.json +++ b/packages/llm/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.18.30", + "version": "1.18.31", "name": "@opencode-ai/llm", "type": "module", "license": "MIT", diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 8cc027275c6f..5e628b3c7055 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -1,6 +1,6 @@ { "$schema": "https://json.schemastore.org/package.json", - "version": "1.18.30", + "version": "1.18.31", "name": "opencode", "type": "module", "license": "MIT", diff --git a/packages/plugin/package.json b/packages/plugin/package.json index d06914cdc8d2..09c1210988cb 100644 --- a/packages/plugin/package.json +++ b/packages/plugin/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/plugin", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/sdk/js/package.json b/packages/sdk/js/package.json index 9777184dfe38..a471612ecaf2 100644 --- a/packages/sdk/js/package.json +++ b/packages/sdk/js/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/sdk", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/server/package.json b/packages/server/package.json index 04cb235ff640..c99bd4ac87d8 100644 --- a/packages/server/package.json +++ b/packages/server/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/server", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/session-ui/package.json b/packages/session-ui/package.json index 7db27630da53..aaba6a52d87c 100644 --- a/packages/session-ui/package.json +++ b/packages/session-ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/session-ui", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/slack/package.json b/packages/slack/package.json index f1aa4602ba6d..86fc0d763af0 100644 --- a/packages/slack/package.json +++ b/packages/slack/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/slack", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "scripts": { diff --git a/packages/stats/app/package.json b/packages/stats/app/package.json index 20d56aa59676..bd1064c18c38 100644 --- a/packages/stats/app/package.json +++ b/packages/stats/app/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/stats-app", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/stats/core/package.json b/packages/stats/core/package.json index d6ffa5fd65f4..3bfb642ea2f5 100644 --- a/packages/stats/core/package.json +++ b/packages/stats/core/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/stats-core", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/stats/server/package.json b/packages/stats/server/package.json index 27f5e23ec0fe..26efcc3aae4b 100644 --- a/packages/stats/server/package.json +++ b/packages/stats/server/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/stats-server", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/tui/package.json b/packages/tui/package.json index 4b9b95b35e68..bc8c1181e9e5 100644 --- a/packages/tui/package.json +++ b/packages/tui/package.json @@ -1,7 +1,7 @@ { "$schema": "https://json.schemastore.org/package.json", "name": "@opencode-ai/tui", - "version": "1.18.30", + "version": "1.18.31", "private": true, "type": "module", "license": "MIT", diff --git a/packages/ui/package.json b/packages/ui/package.json index 28dbce9ecabc..02c1573f0d93 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -1,6 +1,6 @@ { "name": "@opencode-ai/ui", - "version": "1.18.30", + "version": "1.18.31", "type": "module", "license": "MIT", "repository": { diff --git a/packages/web/package.json b/packages/web/package.json index 623f08dfca2e..d5716400d33c 100644 --- a/packages/web/package.json +++ b/packages/web/package.json @@ -2,7 +2,7 @@ "name": "@opencode-ai/web", "type": "module", "license": "MIT", - "version": "1.18.30", + "version": "1.18.31", "scripts": { "dev": "astro dev", "dev:remote": "VITE_API_URL=https://api.opencode.ai astro dev", diff --git a/sdks/vscode/package.json b/sdks/vscode/package.json index 5c43de80758e..779435fece56 100644 --- a/sdks/vscode/package.json +++ b/sdks/vscode/package.json @@ -2,7 +2,7 @@ "name": "opencode", "displayName": "opencode", "description": "opencode for VS Code", - "version": "1.18.30", + "version": "1.18.31", "publisher": "sst-dev", "repository": { "type": "git", From 4ae176520de9ba6615f71bdf188ce1fe2e88388b Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" <219766164+opencode-agent[bot]@users.noreply.github.com> Date: Mon, 14 Sep 2026 14:16:46 -0700 Subject: [PATCH 05/14] chore: add Alan to team members (#49054) Co-authored-by: rekram1-node --- .github/TEAM_MEMBERS | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/TEAM_MEMBERS b/.github/TEAM_MEMBERS index 5268ff59ddc8..866d466a8b4c 100644 --- a/.github/TEAM_MEMBERS +++ b/.github/TEAM_MEMBERS @@ -20,3 +20,4 @@ Slickstef11 usrnk1 vimtor StarpTech +vaprdev From 5cf4e13588c4af05046cbfddebe1d2d97da6cf6b Mon Sep 17 00:00:00 2001 From: vprdev Date: Mon, 14 Sep 2026 14:32:56 -0700 Subject: [PATCH 06/14] fix(console): route new Console keys to inference (#49036) --- .../console/app/src/lib/inference-proxy.ts | 76 ++++++++++--------- 1 file changed, 39 insertions(+), 37 deletions(-) diff --git a/packages/console/app/src/lib/inference-proxy.ts b/packages/console/app/src/lib/inference-proxy.ts index b572c361b655..1eade3ff8fee 100644 --- a/packages/console/app/src/lib/inference-proxy.ts +++ b/packages/console/app/src/lib/inference-proxy.ts @@ -1,5 +1,5 @@ import { Resource } from "@opencode-ai/console-resource" -import { and, Database, eq, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js" +import { and, Database, eq, isNotNull, isNull, sql } from "@opencode-ai/console-core/drizzle/index.js" import { KeyTable } from "@opencode-ai/console-core/schema/key.sql.js" import { ProviderTable } from "@opencode-ai/console-core/schema/provider.sql.js" import { WorkspaceTable } from "@opencode-ai/console-core/schema/workspace.sql.js" @@ -34,7 +34,6 @@ export async function proxyInference( : undefined) if (!path) return undefined - const go = url.pathname.startsWith("/zen/go/") const key = url.pathname.endsWith("/messages") ? request.headers.get("x-api-key") : path.startsWith("/google/") @@ -42,44 +41,23 @@ export async function proxyInference( : request.headers.get("authorization")?.split(" ")[1] if (!key || key === "public") return undefined - // Routing only; the destination owns authentication and revocation after cutover. - const workspace = await Database.use((tx) => - tx - .select({ - id: WorkspaceTable.id, - migratedAt: WorkspaceTable.migrated_at, - provider: ProviderTable.provider, - }) - .from(KeyTable) - .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID)) - .leftJoin( - ProviderTable, - !go && generation?.provider - ? and( - eq(ProviderTable.workspaceID, KeyTable.workspaceID), - eq(ProviderTable.provider, generation.provider), - isNull(ProviderTable.timeDeleted), - sql`length(${ProviderTable.credentials}) > 0`, - ) - : sql`false`, - ) - .where(eq(KeyTable.key, key)) - .limit(1) - .then((rows) => rows[0]), - ) - if (!workspace?.migratedAt) return undefined - const model = workspace.provider ? generation?.model : undefined - if (workspace.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable") + // New Console keys are never in the legacy key table; every legacy key is `sk-`. + const legacy = !key.startsWith("oc_sk_") + const workspace = legacy ? await migratedWorkspace(key, generation?.provider) : undefined + if (legacy && !workspace) return undefined + const model = workspace?.provider ? generation?.model : undefined + if (workspace?.provider && !model) throw new Error("Legacy BYOK model mapping is unavailable") const destination = new URL(Resource.ConsoleMigration.inferenceUrl) // Imported connections must use this same workspace/provider-derived ID. - const target = model - ? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${ - path.startsWith("/google/") - ? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}` - : url.pathname.slice("/zen/v1".length) - }` - : path + const target = + model && workspace + ? `/custom/conn_${workspace.id.slice(4)}_${workspace.provider}${ + path.startsWith("/google/") + ? `/models/${encodeURIComponent(model)}${url.pathname.slice(url.pathname.lastIndexOf(":"))}` + : url.pathname.slice("/zen/v1".length) + }` + : path destination.pathname = `${destination.pathname.replace(/\/$/, "")}${target}` destination.search = url.search destination.hash = "" @@ -109,6 +87,30 @@ export async function proxyInference( return fetch(forwarded, { redirect: "manual" }) } +// Routing only; the destination owns authentication and revocation after cutover. +function migratedWorkspace(key: string, provider?: string) { + return Database.use((tx) => + tx + .select({ id: WorkspaceTable.id, provider: ProviderTable.provider }) + .from(KeyTable) + .innerJoin(WorkspaceTable, eq(WorkspaceTable.id, KeyTable.workspaceID)) + .leftJoin( + ProviderTable, + provider + ? and( + eq(ProviderTable.workspaceID, KeyTable.workspaceID), + eq(ProviderTable.provider, provider), + isNull(ProviderTable.timeDeleted), + sql`length(${ProviderTable.credentials}) > 0`, + ) + : sql`false`, + ) + .where(and(eq(KeyTable.key, key), isNotNull(WorkspaceTable.migrated_at))) + .limit(1) + .then((rows) => rows[0]), + ) +} + export function inferenceUnavailable() { return Response.json( { error: { type: "api_error", message: "Inference routing is unavailable. Please retry later." } }, From 403627b031e1771e4df3d002c9d0df180f6a8cf4 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 14 Sep 2026 17:41:34 -0400 Subject: [PATCH 07/14] deepseek v4.1 flash --- packages/console/app/src/routes/zen/util/handler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/console/app/src/routes/zen/util/handler.ts b/packages/console/app/src/routes/zen/util/handler.ts index 4ef8b7a2089a..414eb09fa66e 100644 --- a/packages/console/app/src/routes/zen/util/handler.ts +++ b/packages/console/app/src/routes/zen/util/handler.ts @@ -160,7 +160,7 @@ export async function handler( if ( authInfo && opts.modelList === "lite" && - ["deepseek-v4-flash", "deepseek-v4-pro"].includes(modelInfo.id) && + ["deepseek-v4.1-flash", "deepseek-flash", "deepseek-v4-flash", "deepseek-v4-pro"].includes(modelInfo.id) && !allowedRegions?.includes("cn") ) throw new RegionError( From 501ff62cbf40d4ff260b48c9f1fc113e9b9a83e1 Mon Sep 17 00:00:00 2001 From: Victor Navarro Date: Wed, 16 Sep 2026 15:07:22 +0200 Subject: [PATCH 08/14] fix(console): exclude migrated workspaces from selection (#49336) --- packages/console/app/src/routes/auth/index.ts | 6 ++++++ packages/console/app/src/routes/workspace-picker.tsx | 1 + packages/console/app/src/routes/workspace/common.tsx | 1 + 3 files changed, 8 insertions(+) diff --git a/packages/console/app/src/routes/auth/index.ts b/packages/console/app/src/routes/auth/index.ts index 0fefb98933ea..3840d653e13b 100644 --- a/packages/console/app/src/routes/auth/index.ts +++ b/packages/console/app/src/routes/auth/index.ts @@ -1,4 +1,5 @@ import { redirect } from "@solidjs/router" +import { Resource } from "@opencode-ai/console-resource" import type { APIEvent } from "@solidjs/start/server" import { getLastSeenWorkspaceID } from "../workspace/common" import { localeFromRequest, route } from "~/lib/language" @@ -7,6 +8,11 @@ export async function GET(input: APIEvent) { const locale = localeFromRequest(input.request) try { const workspaceID = await getLastSeenWorkspaceID() + if (!workspaceID) { + const destination = Resource.ConsoleMigration.consoleUrl + if (!destination) throw new Error("New Console URL is not configured") + return redirect(`${destination}/login`, { headers: { "Cache-Control": "no-store" } }) + } return redirect(route(locale, `/workspace/${workspaceID}`)) } catch { return redirect("/auth/authorize") diff --git a/packages/console/app/src/routes/workspace-picker.tsx b/packages/console/app/src/routes/workspace-picker.tsx index 83f5582ebe09..1bd5fa2f8f5c 100644 --- a/packages/console/app/src/routes/workspace-picker.tsx +++ b/packages/console/app/src/routes/workspace-picker.tsx @@ -27,6 +27,7 @@ const getWorkspaces = query(async () => { and( eq(UserTable.accountID, Actor.account()), isNull(WorkspaceTable.timeDeleted), + isNull(WorkspaceTable.migrated_at), isNull(UserTable.timeDeleted), ), ), diff --git a/packages/console/app/src/routes/workspace/common.tsx b/packages/console/app/src/routes/workspace/common.tsx index fb315eefd54e..a5384d9f422a 100644 --- a/packages/console/app/src/routes/workspace/common.tsx +++ b/packages/console/app/src/routes/workspace/common.tsx @@ -53,6 +53,7 @@ export async function getLastSeenWorkspaceID() { eq(UserTable.accountID, actor.properties.accountID), isNull(UserTable.timeDeleted), isNull(WorkspaceTable.timeDeleted), + isNull(WorkspaceTable.migrated_at), ), ) .orderBy(desc(UserTable.timeSeen)) From ee91f190c5786e2d2ae71bbbdc91230568dedec4 Mon Sep 17 00:00:00 2001 From: Jack Date: Wed, 16 Sep 2026 21:42:09 +0800 Subject: [PATCH 09/14] feat(go): add Union Alpha (#49178) --- .../console/app/src/component/go-models.ts | 9 +++ .../app/src/component/limits-graph.css | 5 ++ .../app/src/component/limits-graph.tsx | 72 ++++++++++++++----- packages/console/app/src/i18n/ar.ts | 3 +- packages/console/app/src/i18n/br.ts | 3 +- packages/console/app/src/i18n/da.ts | 3 +- packages/console/app/src/i18n/de.ts | 3 +- packages/console/app/src/i18n/en.ts | 3 +- packages/console/app/src/i18n/es.ts | 3 +- packages/console/app/src/i18n/fr.ts | 3 +- packages/console/app/src/i18n/it.ts | 3 +- packages/console/app/src/i18n/ja.ts | 3 +- packages/console/app/src/i18n/ko.ts | 3 +- packages/console/app/src/i18n/no.ts | 3 +- packages/console/app/src/i18n/pl.ts | 3 +- packages/console/app/src/i18n/ru.ts | 3 +- packages/console/app/src/i18n/th.ts | 3 +- packages/console/app/src/i18n/tr.ts | 3 +- packages/console/app/src/i18n/uk.ts | 3 +- packages/console/app/src/i18n/zh.ts | 3 +- packages/console/app/src/i18n/zht.ts | 3 +- packages/console/app/src/routes/go/index.tsx | 3 +- .../routes/workspace/[id]/go/lite-section.tsx | 3 +- packages/web/src/content/docs/ar/go.mdx | 5 ++ packages/web/src/content/docs/ar/zen.mdx | 3 + packages/web/src/content/docs/bs/go.mdx | 5 ++ packages/web/src/content/docs/bs/zen.mdx | 3 + packages/web/src/content/docs/da/go.mdx | 5 ++ packages/web/src/content/docs/da/zen.mdx | 3 + packages/web/src/content/docs/de/go.mdx | 5 ++ packages/web/src/content/docs/de/zen.mdx | 3 + packages/web/src/content/docs/es/go.mdx | 5 ++ packages/web/src/content/docs/es/zen.mdx | 3 + packages/web/src/content/docs/fr/go.mdx | 5 ++ packages/web/src/content/docs/fr/zen.mdx | 3 + packages/web/src/content/docs/go.mdx | 5 ++ packages/web/src/content/docs/it/go.mdx | 5 ++ packages/web/src/content/docs/it/zen.mdx | 3 + packages/web/src/content/docs/ja/go.mdx | 5 ++ packages/web/src/content/docs/ja/zen.mdx | 3 + packages/web/src/content/docs/ko/go.mdx | 5 ++ packages/web/src/content/docs/ko/zen.mdx | 3 + packages/web/src/content/docs/nb/go.mdx | 5 ++ packages/web/src/content/docs/nb/zen.mdx | 3 + packages/web/src/content/docs/pl/go.mdx | 5 ++ packages/web/src/content/docs/pl/zen.mdx | 3 + packages/web/src/content/docs/pt-br/go.mdx | 5 ++ packages/web/src/content/docs/pt-br/zen.mdx | 3 + packages/web/src/content/docs/ru/go.mdx | 5 ++ packages/web/src/content/docs/ru/zen.mdx | 3 + packages/web/src/content/docs/th/go.mdx | 5 ++ packages/web/src/content/docs/th/zen.mdx | 3 + packages/web/src/content/docs/tr/go.mdx | 5 ++ packages/web/src/content/docs/tr/zen.mdx | 3 + packages/web/src/content/docs/zen.mdx | 3 + packages/web/src/content/docs/zh-cn/go.mdx | 5 ++ packages/web/src/content/docs/zh-cn/zen.mdx | 3 + packages/web/src/content/docs/zh-tw/go.mdx | 5 ++ packages/web/src/content/docs/zh-tw/zen.mdx | 3 + 59 files changed, 253 insertions(+), 37 deletions(-) diff --git a/packages/console/app/src/component/go-models.ts b/packages/console/app/src/component/go-models.ts index 6df79f4a3921..ca8c63bacfd6 100644 --- a/packages/console/app/src/component/go-models.ts +++ b/packages/console/app/src/component/go-models.ts @@ -50,4 +50,13 @@ export const goModels = [ allowance: 60, regions: true, }, + { + id: "union-alpha", + name: "Union Alpha", + requests: Infinity, + allowance: Infinity, + featured: true, + fresh: true, + unlimited: true, + }, ].sort((a, b) => a.requests - b.requests) diff --git a/packages/console/app/src/component/limits-graph.css b/packages/console/app/src/component/limits-graph.css index ddcf2dfece52..88b13199d4fa 100644 --- a/packages/console/app/src/component/limits-graph.css +++ b/packages/console/app/src/component/limits-graph.css @@ -144,6 +144,11 @@ } } + [data-slot="model-row"][data-unlimited] :is([data-slot="requests"], [data-slot="allowance"]) bdi { + font-size: 1.5rem; + line-height: 1; + } + [data-slot="currency"] { color: var(--color-text-weak); } diff --git a/packages/console/app/src/component/limits-graph.tsx b/packages/console/app/src/component/limits-graph.tsx index 410fd48e4392..5abaf73d6df9 100644 --- a/packages/console/app/src/component/limits-graph.tsx +++ b/packages/console/app/src/component/limits-graph.tsx @@ -5,9 +5,11 @@ import { useLanguage } from "~/context/language" import { goModels } from "./go-models" // Compress the request range, with the same domain in both views. -const max = Math.max(...goModels.map((model) => model.requests)) +const max = Math.max(...goModels.filter((model) => Number.isFinite(model.requests)).map((model) => model.requests)) const position = (requests: number) => - 4 + Math.pow(Math.log10(Math.max(requests / 100, 1)) / Math.log10(max / 100), 2.2) * 96 + Number.isFinite(requests) + ? 4 + Math.pow(Math.log10(Math.max(requests / 100, 1)) / Math.log10(max / 100), 2.2) * 88 + : 100 const ticks = [100, 1000, 10000, 40000] export function LimitsGraph(props: { href: string }) { @@ -74,7 +76,13 @@ export function LimitsGraph(props: { href: string }) {
{(model, index) => ( -
+
{model.name} @@ -83,6 +91,9 @@ export function LimitsGraph(props: { href: string }) { {i18n.t("go.graph.bonus", { count: model.bonus! })} + + {i18n.t("go.graph.limitedTime")} +
-
+
-
= 60 ? "" : undefined}> - - {currency().format(model.baseAllowance!)}{" "} +
= 60 ? "" : undefined} + aria-label={model.unlimited ? i18n.t("go.graph.unlimited") : undefined} + > + - - - {(part) => ( - {part.value} - )} - -
)} diff --git a/packages/console/app/src/i18n/ar.ts b/packages/console/app/src/i18n/ar.ts index fac1d6475833..80cb9a9c63db 100644 --- a/packages/console/app/src/i18n/ar.ts +++ b/packages/console/app/src/i18n/ar.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "يحصل DeepSeek V4.1 Flash على حدود استخدام مضاعفة 4 مرات لفترة محدودة", + "go.promo.unionAlpha": "يتوفر Union Alpha مجانًا لفترة محدودة", "go.graph.bonus": "استخدام مضاعف {{count}} مرات", "nav.github": "GitHub", "nav.docs": "الوثائق", @@ -282,6 +282,7 @@ export const dict = { "go.graph.showLess": "عرض نماذج أقل", "go.graph.limitedRegions": "مناطق محدودة", "go.graph.limitedTime": "لفترة محدودة", + "go.graph.unlimited": "غير محدود", "go.graph.usageLimits": "حدود الاستخدام", "go.graph.aria": "الطلبات كل 5 ساعات: {{free}} مقابل {{go}}", diff --git a/packages/console/app/src/i18n/br.ts b/packages/console/app/src/i18n/br.ts index a2e5867a63dc..c0fa12fcb00d 100644 --- a/packages/console/app/src/i18n/br.ts +++ b/packages/console/app/src/i18n/br.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash tem limites de uso 4x maiores por tempo limitado", + "go.promo.unionAlpha": "O Union Alpha está grátis por tempo limitado", "go.graph.bonus": "{{count}}× mais uso", "nav.github": "GitHub", "nav.docs": "Documentação", @@ -288,6 +288,7 @@ export const dict = { "go.graph.showLess": "Mostrar menos modelos", "go.graph.limitedRegions": "regiões limitadas", "go.graph.limitedTime": "tempo limitado", + "go.graph.unlimited": "ilimitado", "go.graph.usageLimits": "Limites de uso", "go.graph.aria": "Requisições por 5h: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/da.ts b/packages/console/app/src/i18n/da.ts index d2787bb611eb..5d310d74c147 100644 --- a/packages/console/app/src/i18n/da.ts +++ b/packages/console/app/src/i18n/da.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash får firedoblet brugsgrænse i en begrænset periode", + "go.promo.unionAlpha": "Union Alpha er gratis i en begrænset periode", "go.graph.bonus": "{{count}}× forbrug", "nav.github": "GitHub", "nav.docs": "Dokumentation", @@ -285,6 +285,7 @@ export const dict = { "go.graph.showLess": "Vis færre modeller", "go.graph.limitedRegions": "begrænsede regioner", "go.graph.limitedTime": "begrænset periode", + "go.graph.unlimited": "ubegrænset", "go.graph.usageLimits": "Forbrugsgrænser", "go.graph.aria": "Forespørgsler pr. 5t: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/de.ts b/packages/console/app/src/i18n/de.ts index 8fb78e76e611..2dfbd2830b38 100644 --- a/packages/console/app/src/i18n/de.ts +++ b/packages/console/app/src/i18n/de.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash erhält für begrenzte Zeit 4x Nutzungslimits", + "go.promo.unionAlpha": "Union Alpha ist für begrenzte Zeit kostenlos", "go.graph.bonus": "{{count}}× Nutzung", "nav.github": "GitHub", "nav.docs": "Dokumentation", @@ -287,6 +287,7 @@ export const dict = { "go.graph.showLess": "Weniger Modelle anzeigen", "go.graph.limitedRegions": "begrenzte Regionen", "go.graph.limitedTime": "begrenzte Zeit", + "go.graph.unlimited": "unbegrenzt", "go.graph.usageLimits": "Nutzungslimits", "go.graph.aria": "Anfragen pro 5h: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/en.ts b/packages/console/app/src/i18n/en.ts index 4469c3353c51..33664e8eed0d 100644 --- a/packages/console/app/src/i18n/en.ts +++ b/packages/console/app/src/i18n/en.ts @@ -1,5 +1,5 @@ export const dict = { - "go.promo.deepseek": "DeepSeek V4.1 Flash gets 4× usage limits for a limited time", + "go.promo.unionAlpha": "Union Alpha is free for a limited time", "go.graph.bonus": "{{count}}× usage", "nav.github": "GitHub", "nav.docs": "Docs", @@ -282,6 +282,7 @@ export const dict = { "go.graph.showLess": "Show fewer models", "go.graph.limitedRegions": "limited regions", "go.graph.limitedTime": "limited time", + "go.graph.unlimited": "unlimited", "go.graph.tick": "{{n}}x", "go.graph.usageLimits": "Usage limits", "go.graph.aria": "Requests per 5h: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/es.ts b/packages/console/app/src/i18n/es.ts index 9750bc584e27..58c3279f7e54 100644 --- a/packages/console/app/src/i18n/es.ts +++ b/packages/console/app/src/i18n/es.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash tiene límites de uso 4x mayores por tiempo limitado", + "go.promo.unionAlpha": "Union Alpha es gratis por tiempo limitado", "go.graph.bonus": "{{count}}× de uso", "nav.github": "GitHub", "nav.docs": "Documentación", @@ -289,6 +289,7 @@ export const dict = { "go.graph.showLess": "Mostrar menos modelos", "go.graph.limitedRegions": "regiones limitadas", "go.graph.limitedTime": "tiempo limitado", + "go.graph.unlimited": "ilimitado", "go.graph.usageLimits": "Límites de uso", "go.graph.aria": "Solicitudes por 5h: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/fr.ts b/packages/console/app/src/i18n/fr.ts index 5281b6b3e54f..ba63215ffd40 100644 --- a/packages/console/app/src/i18n/fr.ts +++ b/packages/console/app/src/i18n/fr.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash bénéficie de limites d’utilisation 4x supérieures pour une durée limitée", + "go.promo.unionAlpha": "Union Alpha est gratuit pendant une durée limitée", "go.graph.bonus": "{{count}}× d’utilisation", "app.meta.description": "OpenCode - L'agent de code open source.", "nav.github": "GitHub", @@ -290,6 +290,7 @@ export const dict = { "go.graph.showLess": "Afficher moins de modèles", "go.graph.limitedRegions": "régions limitées", "go.graph.limitedTime": "durée limitée", + "go.graph.unlimited": "illimité", "go.graph.usageLimits": "Limites d’utilisation", "go.graph.aria": "Requêtes par 5h : {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/it.ts b/packages/console/app/src/i18n/it.ts index cb2f3d7d7a83..d84600279552 100644 --- a/packages/console/app/src/i18n/it.ts +++ b/packages/console/app/src/i18n/it.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash offre limiti di utilizzo 4x superiori per un periodo limitato", + "go.promo.unionAlpha": "Union Alpha è gratuito per un periodo limitato", "go.graph.bonus": "Utilizzo {{count}}×", "nav.github": "GitHub", "nav.docs": "Documentazione", @@ -286,6 +286,7 @@ export const dict = { "go.graph.showLess": "Mostra meno modelli", "go.graph.limitedRegions": "regioni limitate", "go.graph.limitedTime": "periodo limitato", + "go.graph.unlimited": "illimitato", "go.graph.usageLimits": "Limiti di utilizzo", "go.graph.aria": "Richieste ogni 5h: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/ja.ts b/packages/console/app/src/i18n/ja.ts index 2ae754c47d90..b1b0b49a41e7 100644 --- a/packages/console/app/src/i18n/ja.ts +++ b/packages/console/app/src/i18n/ja.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flashの利用上限が期間限定で4倍に", + "go.promo.unionAlpha": "Union Alphaは期間限定で無料です", "go.graph.bonus": "利用枠{{count}}倍", "nav.github": "GitHub", "nav.docs": "ドキュメント", @@ -285,6 +285,7 @@ export const dict = { "go.graph.showLess": "折りたたむ", "go.graph.limitedRegions": "一部の地域に限定", "go.graph.limitedTime": "期間限定", + "go.graph.unlimited": "無制限", "go.graph.usageLimits": "利用制限", "go.graph.aria": "5時間あたりのリクエスト数: {{free}} 対 {{go}}", diff --git a/packages/console/app/src/i18n/ko.ts b/packages/console/app/src/i18n/ko.ts index e9b5c92071c4..18f2b2dca5b8 100644 --- a/packages/console/app/src/i18n/ko.ts +++ b/packages/console/app/src/i18n/ko.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash 사용 한도가 한시적으로 4배 확대됩니다", + "go.promo.unionAlpha": "Union Alpha는 한정 기간 동안 무료로 이용할 수 있습니다", "go.graph.bonus": "사용량 {{count}}배", "nav.github": "GitHub", "nav.docs": "문서", @@ -281,6 +281,7 @@ export const dict = { "go.graph.showLess": "접기", "go.graph.limitedRegions": "일부 지역에서만 제공", "go.graph.limitedTime": "한정된 기간", + "go.graph.unlimited": "무제한", "go.graph.usageLimits": "사용 한도", "go.graph.aria": "5시간당 요청 수: {{free}} 대 {{go}}", diff --git a/packages/console/app/src/i18n/no.ts b/packages/console/app/src/i18n/no.ts index fc2636a30057..64f75c648670 100644 --- a/packages/console/app/src/i18n/no.ts +++ b/packages/console/app/src/i18n/no.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash får 4x bruksgrense i en begrenset periode", + "go.promo.unionAlpha": "Union Alpha er gratis i en begrenset periode", "go.graph.bonus": "{{count}}× bruk", "nav.github": "GitHub", "nav.docs": "Dokumentasjon", @@ -285,6 +285,7 @@ export const dict = { "go.graph.showLess": "Vis færre modeller", "go.graph.limitedRegions": "begrensede regioner", "go.graph.limitedTime": "begrenset periode", + "go.graph.unlimited": "ubegrenset", "go.graph.usageLimits": "Bruksgrenser", "go.graph.aria": "Forespørsler per 5t: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/pl.ts b/packages/console/app/src/i18n/pl.ts index 4a4e1ba724a6..996d421bc8a0 100644 --- a/packages/console/app/src/i18n/pl.ts +++ b/packages/console/app/src/i18n/pl.ts @@ -2,7 +2,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash oferuje 4x wyższe limity użycia przez ograniczony czas", + "go.promo.unionAlpha": "Union Alpha jest dostępny bezpłatnie przez ograniczony czas", "go.graph.bonus": "{{count}}× większy limit", "nav.github": "GitHub", "nav.docs": "Dokumentacja", @@ -287,6 +287,7 @@ export const dict = { "go.graph.showLess": "Pokaż mniej modeli", "go.graph.limitedRegions": "ograniczone regiony", "go.graph.limitedTime": "ograniczony czas", + "go.graph.unlimited": "bez limitu", "go.graph.usageLimits": "Limity użycia", "go.graph.aria": "Żądania na 5h: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/ru.ts b/packages/console/app/src/i18n/ru.ts index 37f6e43b06d6..fc4e4dc2b040 100644 --- a/packages/console/app/src/i18n/ru.ts +++ b/packages/console/app/src/i18n/ru.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash получает 4x лимиты использования на ограниченное время", + "go.promo.unionAlpha": "Union Alpha можно использовать бесплатно в течение ограниченного времени", "go.graph.bonus": "Лимит ×{{count}}", "nav.github": "GitHub", "nav.docs": "Документация", @@ -290,6 +290,7 @@ export const dict = { "go.graph.showLess": "Показать меньше моделей", "go.graph.limitedRegions": "доступно в отдельных регионах", "go.graph.limitedTime": "ограниченное время", + "go.graph.unlimited": "без ограничений", "go.graph.usageLimits": "Лимиты использования", "go.graph.aria": "Запросов за 5ч: {{free}} против {{go}}", diff --git a/packages/console/app/src/i18n/th.ts b/packages/console/app/src/i18n/th.ts index 97a80f039418..860f3c595d74 100644 --- a/packages/console/app/src/i18n/th.ts +++ b/packages/console/app/src/i18n/th.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash เพิ่มโควตาการใช้งานเป็น 4 เท่าในช่วงเวลาจำกัด", + "go.promo.unionAlpha": "ใช้ Union Alpha ฟรีในช่วงเวลาจำกัด", "go.graph.bonus": "ใช้งาน {{count}} เท่า", "nav.github": "GitHub", "nav.docs": "เอกสาร", @@ -284,6 +284,7 @@ export const dict = { "go.graph.showLess": "แสดงโมเดลน้อยลง", "go.graph.limitedRegions": "เฉพาะบางภูมิภาค", "go.graph.limitedTime": "ช่วงเวลาจำกัด", + "go.graph.unlimited": "ไม่จำกัด", "go.graph.usageLimits": "ขีดจำกัดการใช้งาน", "go.graph.aria": "คำขอต่อ 5 ชม.: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/tr.ts b/packages/console/app/src/i18n/tr.ts index 4289706cc66e..390ce8eccfd6 100644 --- a/packages/console/app/src/i18n/tr.ts +++ b/packages/console/app/src/i18n/tr.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash sınırlı bir süre için 4x kullanım limiti sunuyor", + "go.promo.unionAlpha": "Union Alpha sınırlı bir süre boyunca ücretsiz", "go.graph.bonus": "{{count}}× kullanım", "nav.github": "GitHub", "nav.docs": "Dokümantasyon", @@ -287,6 +287,7 @@ export const dict = { "go.graph.showLess": "Daha az model göster", "go.graph.limitedRegions": "sınırlı bölgeler", "go.graph.limitedTime": "sınırlı süre", + "go.graph.unlimited": "sınırsız", "go.graph.usageLimits": "Kullanım limitleri", "go.graph.aria": "5 saatlik istekler: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/uk.ts b/packages/console/app/src/i18n/uk.ts index 4efac1d76762..f9338c587c78 100644 --- a/packages/console/app/src/i18n/uk.ts +++ b/packages/console/app/src/i18n/uk.ts @@ -2,7 +2,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash отримує 4x ліміти використання протягом обмеженого часу", + "go.promo.unionAlpha": "Union Alpha можна використовувати безкоштовно протягом обмеженого часу", "go.graph.bonus": "Ліміт ×{{count}}", "nav.github": "GitHub", "nav.docs": "Документація", @@ -285,6 +285,7 @@ export const dict = { "go.graph.showLess": "Показати менше моделей", "go.graph.limitedRegions": "обмежені регіони", "go.graph.limitedTime": "обмежений час", + "go.graph.unlimited": "без обмежень", "go.graph.usageLimits": "Ліміти використання", "go.graph.aria": "Запитів за 5 год: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/zh.ts b/packages/console/app/src/i18n/zh.ts index 8c1aff6f6083..76bc605d6c6b 100644 --- a/packages/console/app/src/i18n/zh.ts +++ b/packages/console/app/src/i18n/zh.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash 限时享受 4 倍使用额度", + "go.promo.unionAlpha": "Union Alpha 限时免费", "go.graph.bonus": "{{count}} 倍用量", "nav.github": "GitHub", "nav.docs": "文档", @@ -274,6 +274,7 @@ export const dict = { "go.graph.showLess": "收起模型", "go.graph.limitedRegions": "仅限部分地区", "go.graph.limitedTime": "限时", + "go.graph.unlimited": "无限制", "go.graph.usageLimits": "使用限制", "go.graph.aria": "每 5 小时请求数: {{free}} vs {{go}}", diff --git a/packages/console/app/src/i18n/zht.ts b/packages/console/app/src/i18n/zht.ts index a4a5f4bd4a73..50bfb1cac458 100644 --- a/packages/console/app/src/i18n/zht.ts +++ b/packages/console/app/src/i18n/zht.ts @@ -3,7 +3,7 @@ import { dict as en } from "./en" export const dict = { ...en, - "go.promo.deepseek": "DeepSeek V4.1 Flash 限時享有 4 倍使用額度", + "go.promo.unionAlpha": "Union Alpha 限時免費", "go.graph.bonus": "{{count}} 倍用量", "nav.github": "GitHub", "nav.docs": "文件", @@ -273,6 +273,7 @@ export const dict = { "go.graph.showLess": "收起模型", "go.graph.limitedRegions": "僅限部分地區", "go.graph.limitedTime": "限時", + "go.graph.unlimited": "無限制", "go.graph.usageLimits": "使用限制", "go.graph.aria": "每 5 小時請求數:{{free}} vs {{go}}", diff --git a/packages/console/app/src/routes/go/index.tsx b/packages/console/app/src/routes/go/index.tsx index 95f0e338947a..e2425748e84d 100644 --- a/packages/console/app/src/routes/go/index.tsx +++ b/packages/console/app/src/routes/go/index.tsx @@ -52,6 +52,7 @@ const models = [ { name: "DeepSeek V4 Flash Vision Exp", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" }, { name: "Hy4 preview", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" }, { name: "Hy3", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" }, + { name: "Union Alpha", training: "go.faq.a5.notUsed", retention: "go.faq.a5.retention0" }, ] as const export default function Home() { @@ -84,7 +85,7 @@ export default function Home() {
{i18n.t("home.banner.badge")}
- {i18n.t("go.promo.deepseek")} + {i18n.t("go.promo.unionAlpha")}
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 ed3c4d740676..4a40d931d2cf 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 @@ -667,8 +667,9 @@ export function LiteSection(props: { lite: LiteSubscription | undefined }) {
  • MiMo-V2.5-Pro
  • Hy4 preview
  • Hy3
  • +
  • Union Alpha
  • -

    {i18n.t("go.promo.deepseek")}

    +

    {i18n.t("go.promo.unionAlpha")}

    {i18n.t("workspace.lite.promo.footer")}