chore: merge dev
This commit is contained in:
@@ -40,7 +40,15 @@ export function callAuthProbe(scenario: ActiveScenario, credentials: "missing" |
|
||||
})
|
||||
}
|
||||
|
||||
const appCache: Partial<Record<string, BackendApp>> = {}
|
||||
type CachedApp = BackendApp & { readonly dispose: () => Promise<void> }
|
||||
|
||||
const appCache: Partial<Record<string, CachedApp>> = {}
|
||||
|
||||
export async function disposeApps() {
|
||||
const apps = Object.values(appCache)
|
||||
for (const key of Object.keys(appCache)) delete appCache[key]
|
||||
await Promise.all(apps.flatMap((app) => (app === undefined ? [] : [app.dispose()])))
|
||||
}
|
||||
|
||||
function app(modules: Runtime, options: CallOptions) {
|
||||
const username = options.auth?.username
|
||||
@@ -48,7 +56,7 @@ function app(modules: Runtime, options: CallOptions) {
|
||||
const cacheKey = `${username ?? ""}:${password ?? ""}`
|
||||
if (appCache[cacheKey]) return appCache[cacheKey]
|
||||
|
||||
const handler = HttpRouter.toWebHandler(
|
||||
const web = HttpRouter.toWebHandler(
|
||||
modules.HttpApiApp.routes.pipe(
|
||||
Layer.provide(
|
||||
ConfigProvider.layer(
|
||||
@@ -57,10 +65,11 @@ function app(modules: Runtime, options: CallOptions) {
|
||||
),
|
||||
),
|
||||
{ disableLogger: true, memoMap: modules.memoMap },
|
||||
).handler
|
||||
)
|
||||
return (appCache[cacheKey] = {
|
||||
dispose: web.dispose,
|
||||
request(input: string | URL | Request, init?: RequestInit) {
|
||||
return handler(
|
||||
return web.handler(
|
||||
input instanceof Request ? input : new Request(new URL(input, "http://localhost"), init),
|
||||
modules.HttpApiApp.context,
|
||||
)
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
import { color, printHeader, printResults } from "./report"
|
||||
import { coverageResult, parseOptions, routeKey, routeKeys, selectedScenarios } from "./routing"
|
||||
import { runScenario } from "./runner"
|
||||
import { disposeApps } from "./backend"
|
||||
import { runtime } from "./runtime"
|
||||
import { type Scenario } from "./types"
|
||||
|
||||
@@ -656,7 +657,8 @@ const scenarios: Scenario[] = [
|
||||
.get("/api/provider/{providerID}", "v2.provider.get")
|
||||
.at((ctx) => ({ path: route("/api/provider/{providerID}", { providerID: "missing" }), headers: ctx.headers() }))
|
||||
.json(404, object, "status"),
|
||||
http.protected.get("/api/permission/request", "v2.permission.request.list").json(200, locationData(array)),
|
||||
http.protected.get("/api/permission/request", "v2.permission.request.list").json(200, array),
|
||||
http.protected.get("/api/question/request", "v2.question.request.list").json(200, array),
|
||||
http.protected
|
||||
.get("/api/session/{sessionID}/permission/request", "v2.session.permission.list")
|
||||
.seeded((ctx) => ctx.session({ title: "Permission list owner" }))
|
||||
@@ -677,7 +679,30 @@ const scenarios: Scenario[] = [
|
||||
body: { reply: "once" },
|
||||
}))
|
||||
.json(404, object, "status"),
|
||||
http.protected.get("/api/permission/saved", "v2.permission.saved.list").json(200, data(array)),
|
||||
http.protected
|
||||
.post("/api/session/{sessionID}/question/request/{requestID}/reply", "v2.session.question.reply")
|
||||
.seeded((ctx) => ctx.session({ title: "Question reply owner" }))
|
||||
.at((ctx) => ({
|
||||
path: route("/api/session/{sessionID}/question/request/{requestID}/reply", {
|
||||
sessionID: ctx.state.id,
|
||||
requestID: "que_httpapi_missing",
|
||||
}),
|
||||
headers: ctx.headers(),
|
||||
body: { answers: [] },
|
||||
}))
|
||||
.json(404, object, "status"),
|
||||
http.protected
|
||||
.post("/api/session/{sessionID}/question/request/{requestID}/reject", "v2.session.question.reject")
|
||||
.seeded((ctx) => ctx.session({ title: "Question reject owner" }))
|
||||
.at((ctx) => ({
|
||||
path: route("/api/session/{sessionID}/question/request/{requestID}/reject", {
|
||||
sessionID: ctx.state.id,
|
||||
requestID: "que_httpapi_missing",
|
||||
}),
|
||||
headers: ctx.headers(),
|
||||
}))
|
||||
.json(404, object, "status"),
|
||||
http.protected.get("/api/permission/saved", "v2.permission.saved.list").json(200, array),
|
||||
http.protected
|
||||
.delete("/api/permission/saved/{id}", "v2.permission.saved.remove")
|
||||
.at((ctx) => ({ path: route("/api/permission/saved/{id}", { id: "psv_httpapi_missing" }), headers: ctx.headers() }))
|
||||
@@ -1432,7 +1457,7 @@ const llmScenarios = new Set([
|
||||
])
|
||||
|
||||
const main = Effect.gen(function* () {
|
||||
yield* Effect.addFinalizer(() => cleanupExercisePaths)
|
||||
yield* Effect.addFinalizer(() => Effect.promise(() => disposeApps()).pipe(Effect.andThen(cleanupExercisePaths)))
|
||||
const options = parseOptions(Bun.argv.slice(2))
|
||||
const modules = yield* Effect.promise(() => runtime())
|
||||
const effectRoutes = routeKeys(OpenApi.fromApi(modules.PublicApi))
|
||||
|
||||
@@ -7,11 +7,12 @@ import type { Config } from "../../../src/config/config"
|
||||
|
||||
import type { MessageV2 } from "../../../src/session/message-v2"
|
||||
import { MessageID, PartID } from "../../../src/session/schema"
|
||||
import { call, callAuthProbe } from "./backend"
|
||||
import { call, callAuthProbe, disposeApps } from "./backend"
|
||||
import { original } from "./environment"
|
||||
import { runtime } from "./runtime"
|
||||
import type { ActiveScenario, Options, ProjectOptions, Result, Scenario, ScenarioContext, SeededContext } from "./types"
|
||||
import { ProviderV2 } from "@opencode-ai/core/provider"
|
||||
import { ModelV2 } from "@opencode-ai/core/model"
|
||||
|
||||
export function runScenario(options: Options) {
|
||||
return (scenario: Scenario) => {
|
||||
@@ -153,7 +154,7 @@ function withContext<A, E>(
|
||||
agent: "build",
|
||||
model: {
|
||||
providerID: ProviderV2.ID.opencode,
|
||||
modelID: ProviderV2.ModelID.make("test"),
|
||||
modelID: ModelV2.ID.make("test"),
|
||||
},
|
||||
}
|
||||
const part: SessionV1.TextPart = {
|
||||
@@ -259,6 +260,7 @@ const resetState = Effect.promise(async () => {
|
||||
const modules = await runtime()
|
||||
Flag.OPENCODE_SERVER_PASSWORD = original.OPENCODE_SERVER_PASSWORD
|
||||
Flag.OPENCODE_SERVER_USERNAME = original.OPENCODE_SERVER_USERNAME
|
||||
await disposeApps()
|
||||
await modules.disposeAllInstances()
|
||||
await modules.resetDatabase()
|
||||
await Bun.sleep(25)
|
||||
|
||||
@@ -2,7 +2,7 @@ export type Runtime = {
|
||||
PublicApi: (typeof import("../../../src/server/routes/instance/httpapi/public"))["PublicApi"]
|
||||
HttpApiApp: (typeof import("../../../src/server/routes/instance/httpapi/server"))["HttpApiApp"]
|
||||
AppLayer: (typeof import("../../../src/effect/app-runtime"))["AppLayer"]
|
||||
memoMap: (typeof import("@opencode-ai/core/effect/memo-map"))["memoMap"]
|
||||
memoMap: import("effect").Layer.MemoMap
|
||||
InstanceRef: (typeof import("../../../src/effect/instance-ref"))["InstanceRef"]
|
||||
InstanceStore: (typeof import("../../../src/project/instance-store"))["InstanceStore"]
|
||||
Session: (typeof import("../../../src/session/session"))["Session"]
|
||||
@@ -22,7 +22,7 @@ export function runtime() {
|
||||
const publicApi = await import("../../../src/server/routes/instance/httpapi/public")
|
||||
const httpApiServer = await import("../../../src/server/routes/instance/httpapi/server")
|
||||
const appRuntime = await import("../../../src/effect/app-runtime")
|
||||
const memoMap = await import("@opencode-ai/core/effect/memo-map")
|
||||
const { Layer } = await import("effect")
|
||||
const instanceRef = await import("../../../src/effect/instance-ref")
|
||||
const instanceStore = await import("../../../src/project/instance-store")
|
||||
const session = await import("../../../src/session/session")
|
||||
@@ -36,7 +36,7 @@ export function runtime() {
|
||||
PublicApi: publicApi.PublicApi,
|
||||
HttpApiApp: httpApiServer.HttpApiApp,
|
||||
AppLayer: appRuntime.AppLayer,
|
||||
memoMap: memoMap.memoMap,
|
||||
memoMap: Layer.makeMemoMapUnsafe(),
|
||||
InstanceRef: instanceRef.InstanceRef,
|
||||
InstanceStore: instanceStore.InstanceStore,
|
||||
Session: session.Session,
|
||||
|
||||
Reference in New Issue
Block a user