From 85c16926c4d4c1da8f09d4ac497f7dab8d6ae74e Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Tue, 31 Mar 2026 10:06:40 -0500 Subject: [PATCH] chore: use paid zen model in e2e --- .github/workflows/test.yml | 3 +++ packages/app/e2e/fixtures.ts | 16 +++++++++++++--- packages/opencode/script/seed-e2e.ts | 15 +++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 9c58be30ab..f184d1ddb3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -100,6 +100,9 @@ jobs: run: bun --cwd packages/app test:e2e:local env: CI: true + OPENCODE_API_KEY: ${{ secrets.OPENCODE_API_KEY }} + OPENCODE_E2E_MODEL: opencode/claude-haiku-4-5 + OPENCODE_E2E_REQUIRE_PAID: "true" timeout-minutes: 30 - name: Upload Playwright artifacts diff --git a/packages/app/e2e/fixtures.ts b/packages/app/e2e/fixtures.ts index 7232df6877..ca06858a45 100644 --- a/packages/app/e2e/fixtures.ts +++ b/packages/app/e2e/fixtures.ts @@ -15,6 +15,16 @@ import { createSdk, dirSlug, getWorktree, sessionPath } from "./utils" export const settingsKey = "settings.v3" +const seedModel = (() => { + const [providerID = "opencode", modelID = "big-pickle"] = ( + process.env.OPENCODE_E2E_MODEL ?? "opencode/big-pickle" + ).split("/") + return { + providerID: providerID || "opencode", + modelID: modelID || "big-pickle", + } +})() + type TestFixtures = { sdk: ReturnType gotoSession: (sessionID?: string) => Promise @@ -125,7 +135,7 @@ export const test = base.extend({ async function seedStorage(page: Page, input: { directory: string; extra?: string[] }) { await seedProjects(page, input) - await page.addInitScript(() => { + await page.addInitScript((model: { providerID: string; modelID: string }) => { const win = window as E2EWindow win.__opencode_e2e = { ...win.__opencode_e2e, @@ -143,12 +153,12 @@ async function seedStorage(page: Page, input: { directory: string; extra?: strin localStorage.setItem( "opencode.global.dat:model", JSON.stringify({ - recent: [{ providerID: "opencode", modelID: "big-pickle" }], + recent: [model], user: [], variant: {}, }), ) - }) + }, seedModel) } export { expect } diff --git a/packages/opencode/script/seed-e2e.ts b/packages/opencode/script/seed-e2e.ts index f5bd7194f2..3f247fa0e9 100644 --- a/packages/opencode/script/seed-e2e.ts +++ b/packages/opencode/script/seed-e2e.ts @@ -2,6 +2,7 @@ const dir = process.env.OPENCODE_E2E_PROJECT_DIR ?? process.cwd() const title = process.env.OPENCODE_E2E_SESSION_TITLE ?? "E2E Session" const text = process.env.OPENCODE_E2E_MESSAGE ?? "Seeded for UI e2e" const model = process.env.OPENCODE_E2E_MODEL ?? "opencode/gpt-5-nano" +const requirePaid = process.env.OPENCODE_E2E_REQUIRE_PAID === "true" const parts = model.split("/") const providerID = parts[0] ?? "opencode" const modelID = parts[1] ?? "gpt-5-nano" @@ -11,6 +12,7 @@ const seed = async () => { const { Instance } = await import("../src/project/instance") const { InstanceBootstrap } = await import("../src/project/bootstrap") const { Config } = await import("../src/config/config") + const { Provider } = await import("../src/provider/provider") const { Session } = await import("../src/session") const { MessageID, PartID } = await import("../src/session/schema") const { Project } = await import("../src/project/project") @@ -25,6 +27,19 @@ const seed = async () => { await Config.waitForDependencies() await ToolRegistry.ids() + if (requirePaid && providerID === "opencode" && !process.env.OPENCODE_API_KEY) { + throw new Error("OPENCODE_API_KEY is required when OPENCODE_E2E_REQUIRE_PAID=true") + } + + const info = await Provider.getModel(ProviderID.make(providerID), ModelID.make(modelID)) + if (requirePaid) { + const paid = + info.cost.input > 0 || info.cost.output > 0 || info.cost.cache.read > 0 || info.cost.cache.write > 0 + if (!paid) { + throw new Error(`OPENCODE_E2E_MODEL must resolve to a paid model: ${providerID}/${modelID}`) + } + } + const session = await Session.create({ title }) const messageID = MessageID.ascending() const partID = PartID.ascending()