summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-03-31 10:06:40 -0500
committerAdam <[email protected]>2026-03-31 10:06:44 -0500
commit85c16926c4d4c1da8f09d4ac497f7dab8d6ae74e (patch)
tree55bced5c782335810386736453f6d6a13349e271
parent2e78fdec43ecf98123813b4b1f1c45125004f73f (diff)
downloadopencode-85c16926c4d4c1da8f09d4ac497f7dab8d6ae74e.tar.gz
opencode-85c16926c4d4c1da8f09d4ac497f7dab8d6ae74e.zip
chore: use paid zen model in e2e
-rw-r--r--.github/workflows/test.yml3
-rw-r--r--packages/app/e2e/fixtures.ts16
-rw-r--r--packages/opencode/script/seed-e2e.ts15
3 files changed, 31 insertions, 3 deletions
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 9c58be30a..f184d1ddb 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 7232df687..ca06858a4 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<typeof createSdk>
gotoSession: (sessionID?: string) => Promise<void>
@@ -125,7 +135,7 @@ export const test = base.extend<TestFixtures, WorkerFixtures>({
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 f5bd7194f..3f247fa0e 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()