89 lines
3.1 KiB
TypeScript
89 lines
3.1 KiB
TypeScript
import fs from "node:fs/promises"
|
|
import path from "node:path"
|
|
import { expect } from "bun:test"
|
|
import { Config } from "@opencode-ai/core/config"
|
|
import { Generate } from "@opencode-ai/core/generate"
|
|
import { makeLocationNode } from "@opencode-ai/util/effect/app-node"
|
|
import { Effect, Layer, Predicate } from "effect"
|
|
import { tmpdir } from "../../core/test/fixture/tmpdir"
|
|
import { it } from "../../core/test/lib/effect"
|
|
import { ServerFetch } from "../src/fetch"
|
|
|
|
const generate = makeLocationNode({
|
|
service: Generate.Service,
|
|
layer: Layer.effect(
|
|
Generate.Service,
|
|
Effect.gen(function* () {
|
|
const config = yield* Config.Service
|
|
return Generate.Service.of({
|
|
text: () =>
|
|
config.entries().pipe(
|
|
Effect.map((entries) =>
|
|
JSON.stringify({
|
|
model: Config.latest(entries, "model"),
|
|
}),
|
|
),
|
|
),
|
|
})
|
|
}),
|
|
),
|
|
deps: [Config.node],
|
|
})
|
|
|
|
it.live("uses base configuration without depending on process.cwd()", () =>
|
|
Effect.acquireUseRelease(
|
|
Effect.promise(() => tmpdir("opencode-generate-endpoint-")),
|
|
(tmp) =>
|
|
Effect.gen(function* () {
|
|
const global = path.join(tmp.path, "global")
|
|
const project = path.join(tmp.path, "project")
|
|
yield* Effect.promise(() => Promise.all([fs.mkdir(global), fs.mkdir(project)]))
|
|
yield* Effect.promise(() =>
|
|
Promise.all([
|
|
fs.writeFile(path.join(global, "opencode.json"), JSON.stringify({ model: "base/default" })),
|
|
fs.writeFile(path.join(project, "opencode.json"), JSON.stringify({ model: "project/default" })),
|
|
]),
|
|
)
|
|
const handler = yield* ServerFetch.make(
|
|
{
|
|
database: { path: ":memory:" },
|
|
config: { directory: global },
|
|
fs: { filewatcher: false },
|
|
},
|
|
{ overrides: [[Generate.node, generate]] },
|
|
)
|
|
|
|
expect(global).not.toBe(process.cwd())
|
|
expect(yield* request(handler, new URL("http://opencode.local/api/generate"))).toEqual({
|
|
model: { providerID: "base", model: "default" },
|
|
})
|
|
|
|
const legacy = new URL("http://opencode.local/api/generate")
|
|
legacy.searchParams.set("location[directory]", project)
|
|
expect(yield* request(handler, legacy)).toEqual({
|
|
model: { providerID: "base", model: "default" },
|
|
})
|
|
}),
|
|
(tmp) => Effect.promise(() => tmp[Symbol.asyncDispose]()),
|
|
),
|
|
)
|
|
|
|
function request(handler: (request: Request) => Promise<Response>, url: URL) {
|
|
return Effect.promise(() =>
|
|
handler(
|
|
new Request(url, {
|
|
method: "POST",
|
|
headers: { "content-type": "application/json" },
|
|
body: JSON.stringify({ prompt: "hello" }),
|
|
}),
|
|
).then(async (response) => {
|
|
expect(response.status).toBe(200)
|
|
const body: unknown = await response.json()
|
|
if (!Predicate.isObject(body) || !Predicate.isObject(body.data) || typeof body.data.text !== "string")
|
|
throw new Error("Expected a generate response")
|
|
const result: unknown = JSON.parse(body.data.text)
|
|
return result
|
|
}),
|
|
)
|
|
}
|