mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-17 01:52:55 +00:00
refactor(instance): retire WithInstance adapter (#27782)
This commit is contained in:
@@ -2,7 +2,6 @@ import { Installation } from "@/installation"
|
||||
import { Server } from "@/server/server"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
import { InstanceRuntime } from "@/project/instance-runtime"
|
||||
import { WithInstance } from "@/project/with-instance"
|
||||
import { Rpc } from "@/util/rpc"
|
||||
import { upgrade } from "@/cli/upgrade"
|
||||
import { Config } from "@/config/config"
|
||||
@@ -77,12 +76,8 @@ export const rpc = {
|
||||
return { url: server.url.toString() }
|
||||
},
|
||||
async checkUpgrade(input: { directory: string }) {
|
||||
await WithInstance.provide({
|
||||
directory: input.directory,
|
||||
fn: async () => {
|
||||
await upgrade().catch(() => {})
|
||||
},
|
||||
})
|
||||
await InstanceRuntime.load({ directory: input.directory })
|
||||
await upgrade().catch(() => {})
|
||||
},
|
||||
async reload() {
|
||||
await AppRuntime.runPromise(
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { AppRuntime } from "@/effect/app-runtime"
|
||||
import type { InstanceContext } from "./instance-context"
|
||||
import { InstanceStore } from "./instance-store"
|
||||
|
||||
export async function provide<R>(input: { directory: string; fn: (ctx: InstanceContext) => R }): Promise<R> {
|
||||
const ctx = await AppRuntime.runPromise(
|
||||
InstanceStore.Service.use((store) => store.load({ directory: input.directory })),
|
||||
)
|
||||
return input.fn(ctx)
|
||||
}
|
||||
|
||||
export * as WithInstance from "./with-instance"
|
||||
@@ -149,7 +149,7 @@ Do not maintain a long file checklist here. It goes stale quickly.
|
||||
When looking for the next target, search for current anti-patterns:
|
||||
|
||||
```bash
|
||||
git grep -n "Effect.runPromise\|ManagedRuntime\|Promise.withResolvers\|Bun.sleep\|WithInstance" -- packages/opencode/test
|
||||
git grep -n "Effect.runPromise\|ManagedRuntime\|Promise.withResolvers\|Bun.sleep\|withTestInstance" -- packages/opencode/test
|
||||
```
|
||||
|
||||
Then choose one file or one small cluster, keep the PR focused, and mention
|
||||
|
||||
@@ -8,13 +8,12 @@ import { EffectFlock } from "@opencode-ai/core/util/effect-flock"
|
||||
|
||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||
import type { InstanceContext } from "../../src/project/instance-context"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
import { Auth } from "../../src/auth"
|
||||
import { Account } from "../../src/account/account"
|
||||
import { AccessToken, AccountID, OrgID } from "../../src/account/schema"
|
||||
import { AppFileSystem } from "@opencode-ai/core/filesystem"
|
||||
import { Env } from "../../src/env"
|
||||
import { provideTestInstance, provideTmpdirInstance } from "../fixture/fixture"
|
||||
import { provideTestInstance, provideTmpdirInstance, withTestInstance } from "../fixture/fixture"
|
||||
import { tmpdir } from "../fixture/fixture"
|
||||
import { InstanceRuntime } from "@/project/instance-runtime"
|
||||
import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner"
|
||||
@@ -136,7 +135,7 @@ async function check(map: (dir: string) => string) {
|
||||
$schema: "https://opencode.ai/config.json",
|
||||
snapshot: false,
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: map(tmp.path),
|
||||
fn: async (ctx) => {
|
||||
const cfg = await load(ctx)
|
||||
@@ -154,7 +153,7 @@ async function check(map: (dir: string) => string) {
|
||||
|
||||
test("loads config with defaults when no files exist", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -170,7 +169,7 @@ test("creates global jsonc config with schema when no global configs exist", asy
|
||||
await clear(true)
|
||||
|
||||
try {
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
await load(ctx)
|
||||
@@ -195,7 +194,7 @@ test("does not create global config when OPENCODE_CONFIG_DIR is set", async () =
|
||||
await clear(true)
|
||||
|
||||
try {
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
await load(ctx)
|
||||
@@ -221,7 +220,7 @@ test("loads JSON config file", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -240,7 +239,7 @@ test("loads shell config field", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -262,7 +261,7 @@ test("updates config and preserves empty shell sentinel", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
await save({ shell: "" }, ctx)
|
||||
@@ -340,7 +339,7 @@ test("loads formatter boolean config", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -358,7 +357,7 @@ test("loads lsp boolean config", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -395,7 +394,7 @@ test("ignores legacy tui keys in opencode config", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -420,7 +419,7 @@ test("loads JSONC config file", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -448,7 +447,7 @@ test("jsonc overrides json in the same directory", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -471,7 +470,7 @@ test("handles environment variable substitution", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -503,7 +502,7 @@ test("preserves env variables when adding $schema to config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -600,7 +599,7 @@ test("handles file inclusion substitution", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -619,7 +618,7 @@ test("handles file inclusion with replacement tokens", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -675,7 +674,7 @@ test("handles agent configuration", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -706,7 +705,7 @@ test("treats agent variant as model-scoped setting (not provider option)", async
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -736,7 +735,7 @@ test("handles command configuration", async () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -761,7 +760,7 @@ test("migrates autoshare to share field", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -788,7 +787,7 @@ test("migrates mode field to agent field", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -820,7 +819,7 @@ Test agent prompt`,
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -853,7 +852,7 @@ Ordered permissions`,
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -891,7 +890,7 @@ Nested agent prompt`,
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -940,7 +939,7 @@ Nested command template`,
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -985,7 +984,7 @@ Nested command template`,
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1005,7 +1004,7 @@ Nested command template`,
|
||||
|
||||
test("updates config and writes to file", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const newConfig = { model: "updated/model" }
|
||||
@@ -1019,7 +1018,7 @@ test("updates config and writes to file", async () => {
|
||||
|
||||
test("gets config directories", async () => {
|
||||
await using tmp = await tmpdir()
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const dirs = await listDirs(ctx)
|
||||
@@ -1049,7 +1048,7 @@ test("does not try to install dependencies in read-only OPENCODE_CONFIG_DIR", as
|
||||
process.env.OPENCODE_CONFIG_DIR = tmp.extra
|
||||
|
||||
try {
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
await load(ctx)
|
||||
@@ -1084,7 +1083,7 @@ test("installs dependencies in writable OPENCODE_CONFIG_DIR", async () => {
|
||||
)
|
||||
|
||||
try {
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
await Effect.runPromise(
|
||||
@@ -1225,7 +1224,7 @@ Helper subagent prompt`,
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1264,7 +1263,7 @@ test("merges instructions arrays from global and local configs", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: path.join(tmp.path, "project"),
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1303,7 +1302,7 @@ test("deduplicates duplicate instructions from global and local configs", async
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: path.join(tmp.path, "project"),
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1438,7 +1437,7 @@ test("migrates legacy tools config to permissions - allow", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1469,7 +1468,7 @@ test("migrates legacy tools config to permissions - deny", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1499,7 +1498,7 @@ test("migrates legacy write tool to edit permission", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1531,7 +1530,7 @@ test("managed settings override user settings", async () => {
|
||||
share: "disabled",
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1559,7 +1558,7 @@ test("managed settings override project settings", async () => {
|
||||
disabled_providers: ["openai"],
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1579,7 +1578,7 @@ test("missing managed settings file is not an error", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1606,7 +1605,7 @@ test("migrates legacy edit tool to edit permission", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1635,7 +1634,7 @@ test("migrates legacy patch tool to edit permission", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1667,7 +1666,7 @@ test("migrates mixed legacy tools config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1702,7 +1701,7 @@ test("merges legacy tools with existing permission config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1739,7 +1738,7 @@ test("permission config preserves user key order", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1822,7 +1821,7 @@ test("project config can override MCP server enabled status", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1878,7 +1877,7 @@ test("MCP config deep merges preserving base config properties", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -1929,7 +1928,7 @@ test("local .opencode config can override MCP from project config", async () =>
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -2295,7 +2294,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -2326,7 +2325,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => {
|
||||
await Filesystem.write(path.join(opencodeDir, "test-cmd.md"), "# Test Command\nThis is a test command.")
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const directories = await listDirs(ctx)
|
||||
@@ -2350,7 +2349,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => {
|
||||
|
||||
try {
|
||||
await using tmp = await tmpdir()
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
// Should still get default config (from global or defaults)
|
||||
@@ -2392,7 +2391,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
// The relative instruction should be skipped without error
|
||||
@@ -2452,7 +2451,7 @@ describe("OPENCODE_DISABLE_PROJECT_CONFIG", () => {
|
||||
process.env["OPENCODE_DISABLE_PROJECT_CONFIG"] = "true"
|
||||
process.env["OPENCODE_CONFIG_DIR"] = configDirTmp.path
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: projectTmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -2487,7 +2486,7 @@ describe("OPENCODE_CONFIG_CONTENT token substitution", () => {
|
||||
|
||||
try {
|
||||
await using tmp = await tmpdir()
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
@@ -2521,7 +2520,7 @@ describe("OPENCODE_CONFIG_CONTENT token substitution", () => {
|
||||
})
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const config = await load(ctx)
|
||||
|
||||
@@ -37,6 +37,10 @@ export async function provideTestInstance<R>(input: {
|
||||
}
|
||||
}
|
||||
|
||||
export async function withTestInstance<R>(input: { directory: string; fn: (ctx: InstanceContext) => R }) {
|
||||
return input.fn(await runTestInstanceStore((store) => store.load({ directory: input.directory })))
|
||||
}
|
||||
|
||||
export async function reloadTestInstance(input: { directory: string }) {
|
||||
return runTestInstanceStore((store) => store.reload(input))
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
import { beforeEach, describe, expect, test } from "bun:test"
|
||||
import path from "path"
|
||||
import { pathToFileURL } from "url"
|
||||
import { tmpdir } from "../fixture/fixture"
|
||||
import { tmpdir, withTestInstance } from "../fixture/fixture"
|
||||
import { LSPClient } from "@/lsp/client"
|
||||
import * as LSPServer from "@/lsp/server"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
|
||||
function spawnFakeServer() {
|
||||
@@ -25,7 +24,7 @@ describe("LSPClient interop", () => {
|
||||
test("handles workspace/workspaceFolders request", async () => {
|
||||
const handle = spawnFakeServer() as any
|
||||
|
||||
const client = await WithInstance.provide({
|
||||
const client = await withTestInstance({
|
||||
directory: process.cwd(),
|
||||
fn: (ctx) =>
|
||||
LSPClient.create({
|
||||
@@ -49,7 +48,7 @@ describe("LSPClient interop", () => {
|
||||
test("handles client/registerCapability request", async () => {
|
||||
const handle = spawnFakeServer() as any
|
||||
|
||||
const client = await WithInstance.provide({
|
||||
const client = await withTestInstance({
|
||||
directory: process.cwd(),
|
||||
fn: (ctx) =>
|
||||
LSPClient.create({
|
||||
@@ -73,7 +72,7 @@ describe("LSPClient interop", () => {
|
||||
test("handles client/unregisterCapability request", async () => {
|
||||
const handle = spawnFakeServer() as any
|
||||
|
||||
const client = await WithInstance.provide({
|
||||
const client = await withTestInstance({
|
||||
directory: process.cwd(),
|
||||
fn: (ctx) =>
|
||||
LSPClient.create({
|
||||
@@ -97,7 +96,7 @@ describe("LSPClient interop", () => {
|
||||
test("initialize does not overclaim unsupported diagnostics capabilities", async () => {
|
||||
const handle = spawnFakeServer() as any
|
||||
|
||||
const client = await WithInstance.provide({
|
||||
const client = await withTestInstance({
|
||||
directory: process.cwd(),
|
||||
fn: (ctx) =>
|
||||
LSPClient.create({
|
||||
@@ -125,7 +124,7 @@ describe("LSPClient interop", () => {
|
||||
gamma: true,
|
||||
}
|
||||
|
||||
const client = await WithInstance.provide({
|
||||
const client = await withTestInstance({
|
||||
directory: process.cwd(),
|
||||
fn: (ctx) =>
|
||||
LSPClient.create({
|
||||
@@ -155,7 +154,7 @@ describe("LSPClient interop", () => {
|
||||
const file = path.join(tmp.path, "client.ts")
|
||||
await Bun.write(file, "first\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
@@ -199,7 +198,7 @@ describe("LSPClient interop", () => {
|
||||
const file = path.join(tmp.path, "client.ts")
|
||||
await Bun.write(file, "const x = 1\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
@@ -246,7 +245,7 @@ describe("LSPClient interop", () => {
|
||||
const file = path.join(tmp.path, "client.ts")
|
||||
await Bun.write(file, "const x = 1\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
@@ -294,7 +293,7 @@ describe("LSPClient interop", () => {
|
||||
const file = path.join(tmp.path, "client.cs")
|
||||
await Bun.write(file, "class C {}\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
@@ -343,7 +342,7 @@ describe("LSPClient interop", () => {
|
||||
const file = path.join(tmp.path, "client.cs")
|
||||
await Bun.write(file, "class C {}\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
@@ -397,7 +396,7 @@ describe("LSPClient interop", () => {
|
||||
await Bun.write(file, "class C {}\n")
|
||||
await Bun.write(related, "class D {}\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
@@ -462,7 +461,7 @@ describe("LSPClient interop", () => {
|
||||
const file = path.join(tmp.path, "client.cs")
|
||||
await Bun.write(file, "class C {}\n")
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const client = await LSPClient.create({
|
||||
|
||||
@@ -3,9 +3,8 @@ import path from "path"
|
||||
import { unlink } from "fs/promises"
|
||||
|
||||
import { ProviderID } from "../../src/provider/schema"
|
||||
import { disposeAllInstances, tmpdir } from "../fixture/fixture"
|
||||
import { disposeAllInstances, tmpdir, withTestInstance } from "../fixture/fixture"
|
||||
import type { InstanceContext } from "../../src/project/instance-context"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
import { Provider } from "@/provider/provider"
|
||||
import { Env } from "../../src/env"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
@@ -64,7 +63,7 @@ test("Bedrock: config region takes precedence over AWS_REGION env var", async ()
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_REGION", "us-east-1")
|
||||
@@ -87,7 +86,7 @@ test("Bedrock: falls back to AWS_REGION env var when no config region", async ()
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_REGION", "eu-west-1")
|
||||
@@ -140,7 +139,7 @@ test("Bedrock: loads when bearer token from auth.json is present", async () => {
|
||||
}),
|
||||
)
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "")
|
||||
@@ -184,7 +183,7 @@ test("Bedrock: config profile takes precedence over AWS_PROFILE env var", async
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "default")
|
||||
@@ -214,7 +213,7 @@ test("Bedrock: includes custom endpoint in options when specified", async () =>
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "default")
|
||||
@@ -245,7 +244,7 @@ test("Bedrock: autoloads when AWS_WEB_IDENTITY_TOKEN_FILE is present", async ()
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_WEB_IDENTITY_TOKEN_FILE", "/var/run/secrets/eks.amazonaws.com/serviceaccount/token")
|
||||
@@ -286,7 +285,7 @@ test("Bedrock: model with us. prefix should not be double-prefixed", async () =>
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "default")
|
||||
@@ -321,7 +320,7 @@ test("Bedrock: model with global. prefix should not be prefixed", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "default")
|
||||
@@ -355,7 +354,7 @@ test("Bedrock: model with eu. prefix should not be double-prefixed", async () =>
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "default")
|
||||
@@ -389,7 +388,7 @@ test("Bedrock: model without prefix in US region should get us. prefix added", a
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "AWS_PROFILE", "default")
|
||||
|
||||
@@ -7,8 +7,7 @@ export {}
|
||||
// import path from "path"
|
||||
|
||||
// import { ProviderID, ModelID } from "../../src/provider/schema"
|
||||
// import { tmpdir } from "../fixture/fixture"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
// import { tmpdir, withTestInstance } from "../fixture/fixture"
|
||||
// import { Provider } from "@/provider/provider"
|
||||
// import { Env } from "../../src/env"
|
||||
// import { Global } from "@opencode-ai/core/global"
|
||||
@@ -25,7 +24,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-gitlab-token")
|
||||
@@ -56,7 +55,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -95,7 +94,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// }),
|
||||
// )
|
||||
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "")
|
||||
@@ -130,7 +129,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// }),
|
||||
// )
|
||||
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "")
|
||||
@@ -162,7 +161,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_INSTANCE_URL", "https://gitlab.company.internal")
|
||||
@@ -193,7 +192,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "env-token")
|
||||
@@ -216,7 +215,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -252,7 +251,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -277,7 +276,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// )
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -301,7 +300,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json" }))
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -349,7 +348,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json" }))
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -372,7 +371,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json" }))
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
@@ -396,7 +395,7 @@ import { WithInstance } from "../../src/project/with-instance"
|
||||
// await Bun.write(path.join(dir, "opencode.json"), JSON.stringify({ $schema: "https://opencode.ai/config.json" }))
|
||||
// },
|
||||
// })
|
||||
// await WithInstance.provide({
|
||||
// await withTestInstance({
|
||||
// directory: tmp.path,
|
||||
// init: async () => {
|
||||
// Env.set("GITLAB_TOKEN", "test-token")
|
||||
|
||||
@@ -2,10 +2,9 @@ import { afterEach, test, expect } from "bun:test"
|
||||
import { mkdir, unlink } from "fs/promises"
|
||||
import path from "path"
|
||||
|
||||
import { disposeAllInstances, tmpdir } from "../fixture/fixture"
|
||||
import { disposeAllInstances, tmpdir, withTestInstance } from "../fixture/fixture"
|
||||
import { Global } from "@opencode-ai/core/global"
|
||||
import type { InstanceContext } from "../../src/project/instance-context"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
import { Plugin } from "../../src/plugin/index"
|
||||
import { ModelsDev } from "@opencode-ai/core/models"
|
||||
import { Provider } from "@/provider/provider"
|
||||
@@ -147,7 +146,7 @@ test("provider loaded from env variable", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -179,7 +178,7 @@ test("provider loaded from config with apiKey option", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -200,7 +199,7 @@ test("disabled_providers excludes provider", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -222,7 +221,7 @@ test("enabled_providers restricts to only listed providers", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -250,7 +249,7 @@ test("model whitelist filters models for provider", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -279,7 +278,7 @@ test("model blacklist excludes specific models", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -312,7 +311,7 @@ test("custom model alias via config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -356,7 +355,7 @@ test("custom provider with npm package", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -433,7 +432,7 @@ test("custom DeepSeek openai-compatible model defaults interleaved reasoning fie
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -467,7 +466,7 @@ test("env variable takes precedence, config merges options", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "env-api-key")
|
||||
@@ -491,7 +490,7 @@ test("getModel returns model for valid provider/model", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -516,7 +515,7 @@ test("getModel throws ModelNotFoundError for invalid model", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -536,7 +535,7 @@ test("getModel throws ModelNotFoundError for invalid provider", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
expect(getModel(ProviderID.make("nonexistent-provider"), ModelID.make("some-model"), ctx)).rejects.toThrow()
|
||||
@@ -567,7 +566,7 @@ test("defaultModel returns first available model when no config set", async () =
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -590,7 +589,7 @@ test("defaultModel respects config model setting", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -723,7 +722,7 @@ test("closest finds model by partial match", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -746,7 +745,7 @@ test("closest returns undefined for nonexistent provider", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const result = await closest(ProviderID.make("nonexistent"), ["model"], ctx)
|
||||
@@ -776,7 +775,7 @@ test("getModel uses realIdByKey for aliased models", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -820,7 +819,7 @@ test("provider api field sets model api.url", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -860,7 +859,7 @@ test("explicit baseURL overrides api field", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -889,7 +888,7 @@ test("model inherits properties from existing database model", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -915,7 +914,7 @@ test("disabled_providers prevents loading even with env var", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "OPENAI_API_KEY", "test-openai-key")
|
||||
@@ -937,7 +936,7 @@ test("enabled_providers with empty array allows no providers", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -965,7 +964,7 @@ test("whitelist and blacklist can be combined", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1005,7 +1004,7 @@ test("model modalities default correctly", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1048,7 +1047,7 @@ test("model with custom cost values", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1072,7 +1071,7 @@ test("getSmallModel returns appropriate small model", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1095,7 +1094,7 @@ test("getSmallModel respects config small_model override", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1119,7 +1118,7 @@ test("getSmallModel ignores invalid config small_model", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1162,7 +1161,7 @@ test("multiple providers can be configured simultaneously", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-anthropic-key")
|
||||
@@ -1205,7 +1204,7 @@ test("provider with custom npm package", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1239,7 +1238,7 @@ test("model alias name defaults to alias key when id differs", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1277,7 +1276,7 @@ test("provider with multiple env var options only includes apiKey when single en
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "MULTI_ENV_KEY_1", "test-key")
|
||||
@@ -1317,7 +1316,7 @@ test("provider with single env var includes apiKey automatically", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "SINGLE_ENV_KEY", "my-api-key")
|
||||
@@ -1352,7 +1351,7 @@ test("model cost overrides existing cost values", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1400,7 +1399,7 @@ test("completely new provider not in database can be configured", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1429,7 +1428,7 @@ test("disabled_providers and enabled_providers interaction", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-anthropic")
|
||||
@@ -1472,7 +1471,7 @@ test("model with tool_call false", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1507,7 +1506,7 @@ test("model defaults tool_call to true when not specified", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1546,7 +1545,7 @@ test("model headers are preserved", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1585,7 +1584,7 @@ test("provider env fallback - second env var used if first missing", async () =>
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
// Only set fallback, not primary
|
||||
@@ -1608,7 +1607,7 @@ test("getModel returns consistent results", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1647,7 +1646,7 @@ test("provider name defaults to id when not in database", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1667,7 +1666,7 @@ test("ModelNotFoundError includes suggestions for typos", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1693,7 +1692,7 @@ test("ModelNotFoundError for provider includes suggestions", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1719,7 +1718,7 @@ test("ModelNotFoundError suggests catalog models for unloaded providers", async
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
remove(ctx, "OPENCODE_API_KEY")
|
||||
@@ -1745,7 +1744,7 @@ test("getProvider returns undefined for nonexistent provider", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const provider = await getProvider(ProviderID.make("nonexistent"), ctx)
|
||||
@@ -1765,7 +1764,7 @@ test("getProvider returns provider info", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1787,7 +1786,7 @@ test("closest returns undefined when no partial match found", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1808,7 +1807,7 @@ test("closest checks multiple query terms in order", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1846,7 +1845,7 @@ test("model limit defaults to zero when not specified", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1878,7 +1877,7 @@ test("provider options are deeply merged", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -1910,7 +1909,7 @@ test("hosted nvidia provider adds billing origin header", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1942,7 +1941,7 @@ test("custom nvidia baseURL adds billing origin header", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -1977,7 +1976,7 @@ test("explicit nvidia billing origin header is preserved", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -2008,7 +2007,7 @@ test("custom model inherits npm package from models.dev provider config", async
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "OPENAI_API_KEY", "test-api-key")
|
||||
@@ -2041,7 +2040,7 @@ test("custom model inherits api.url from models.dev provider", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "OPENROUTER_API_KEY", "test-api-key")
|
||||
@@ -2172,7 +2171,7 @@ test("model variants are generated for reasoning models", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -2208,7 +2207,7 @@ test("model variants can be disabled via config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -2249,7 +2248,7 @@ test("model variants can be customized via config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -2286,7 +2285,7 @@ test("disabled key is stripped from variant config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -2322,7 +2321,7 @@ test("all variants can be disabled via config", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -2358,7 +2357,7 @@ test("variant config merges with generated variants", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-api-key")
|
||||
@@ -2394,7 +2393,7 @@ test("variants filtered in second pass for database models", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "OPENAI_API_KEY", "test-api-key")
|
||||
@@ -2441,7 +2440,7 @@ test("custom model with variants enabled and disabled", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const providers = await list(ctx)
|
||||
@@ -2496,7 +2495,7 @@ test("Google Vertex: retains baseURL for custom proxy", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "GOOGLE_APPLICATION_CREDENTIALS", "test-creds")
|
||||
@@ -2539,7 +2538,7 @@ test("Google Vertex: supports OpenAI compatible models", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "GOOGLE_APPLICATION_CREDENTIALS", "test-creds")
|
||||
@@ -2563,7 +2562,7 @@ test("cloudflare-ai-gateway loads with env variables", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "CLOUDFLARE_ACCOUNT_ID", "test-account")
|
||||
@@ -2593,7 +2592,7 @@ test("cloudflare-ai-gateway forwards config metadata options", async () => {
|
||||
)
|
||||
},
|
||||
})
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "CLOUDFLARE_ACCOUNT_ID", "test-account")
|
||||
@@ -2646,7 +2645,7 @@ test("plugin config providers persist after instance dispose", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
const first = await WithInstance.provide({
|
||||
const first = await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) =>
|
||||
AppRuntime.runPromise(
|
||||
@@ -2663,7 +2662,7 @@ test("plugin config providers persist after instance dispose", async () => {
|
||||
|
||||
await disposeAllInstances()
|
||||
|
||||
const second = await WithInstance.provide({
|
||||
const second = await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => list(ctx),
|
||||
})
|
||||
@@ -2694,7 +2693,7 @@ test("plugin config enabled and disabled providers are honored", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
set(ctx, "ANTHROPIC_API_KEY", "test-anthropic-key")
|
||||
@@ -2718,7 +2717,7 @@ test("opencode loader keeps paid models when config apiKey is present", async ()
|
||||
},
|
||||
})
|
||||
|
||||
const none = await WithInstance.provide({
|
||||
const none = await withTestInstance({
|
||||
directory: base.path,
|
||||
fn: async (ctx) => paid(await list(ctx)),
|
||||
})
|
||||
@@ -2741,7 +2740,7 @@ test("opencode loader keeps paid models when config apiKey is present", async ()
|
||||
},
|
||||
})
|
||||
|
||||
const keyedCount = await WithInstance.provide({
|
||||
const keyedCount = await withTestInstance({
|
||||
directory: keyed.path,
|
||||
fn: async (ctx) => paid(await list(ctx)),
|
||||
})
|
||||
@@ -2762,7 +2761,7 @@ test("opencode loader keeps paid models when auth exists", async () => {
|
||||
},
|
||||
})
|
||||
|
||||
const none = await WithInstance.provide({
|
||||
const none = await withTestInstance({
|
||||
directory: base.path,
|
||||
fn: async (ctx) => paid(await list(ctx)),
|
||||
})
|
||||
@@ -2796,7 +2795,7 @@ test("opencode loader keeps paid models when auth exists", async () => {
|
||||
}),
|
||||
)
|
||||
|
||||
const keyedCount = await WithInstance.provide({
|
||||
const keyedCount = await withTestInstance({
|
||||
directory: keyed.path,
|
||||
fn: async (ctx) => paid(await list(ctx)),
|
||||
})
|
||||
|
||||
@@ -7,13 +7,12 @@ import { makeRuntime } from "../../src/effect/run-service"
|
||||
import { InstanceRef } from "../../src/effect/instance-ref"
|
||||
import { LLM } from "../../src/session/llm"
|
||||
import type { InstanceContext } from "../../src/project/instance-context"
|
||||
import { WithInstance } from "../../src/project/with-instance"
|
||||
import { Provider } from "@/provider/provider"
|
||||
import { ProviderTransform } from "@/provider/transform"
|
||||
import { ModelsDev } from "@opencode-ai/core/models"
|
||||
import { ProviderID, ModelID } from "../../src/provider/schema"
|
||||
import { Filesystem } from "@/util/filesystem"
|
||||
import { tmpdir } from "../fixture/fixture"
|
||||
import { tmpdir, withTestInstance } from "../fixture/fixture"
|
||||
import type { Agent } from "../../src/agent/agent"
|
||||
import { MessageV2 } from "../../src/session/message-v2"
|
||||
import { SessionID, MessageID } from "../../src/session/schema"
|
||||
@@ -361,7 +360,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
@@ -451,7 +450,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
@@ -541,7 +540,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
@@ -658,7 +657,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.openai, ModelID.make(model.id), ctx)
|
||||
@@ -777,7 +776,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.openai, ModelID.make(model.id), ctx)
|
||||
@@ -899,7 +898,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
@@ -1020,7 +1019,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make("anthropic"), ModelID.make(model.id), ctx)
|
||||
@@ -1264,7 +1263,7 @@ describe("session.llm.stream", () => {
|
||||
},
|
||||
})
|
||||
|
||||
await WithInstance.provide({
|
||||
await withTestInstance({
|
||||
directory: tmp.path,
|
||||
fn: async (ctx) => {
|
||||
const resolved = await getModel(ProviderID.make(providerID), ModelID.make(model.id), ctx)
|
||||
|
||||
Reference in New Issue
Block a user