feat(server): add lazy simulation layer replacements (#35024)
This commit is contained in:
parent
bc2e270f82
commit
b0ca5520a1
2 changed files with 37 additions and 10 deletions
|
|
@ -16,7 +16,7 @@ import { SdkPlugins } from "@opencode-ai/core/plugin/sdk"
|
||||||
import { ToolOutputStore } from "@opencode-ai/core/tool-output-store"
|
import { ToolOutputStore } from "@opencode-ai/core/tool-output-store"
|
||||||
import { HttpRouter, HttpServer } from "effect/unstable/http"
|
import { HttpRouter, HttpServer } from "effect/unstable/http"
|
||||||
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
import { HttpApiBuilder } from "effect/unstable/httpapi"
|
||||||
import { Layer, Option } from "effect"
|
import { Effect, Layer, Option } from "effect"
|
||||||
import { Api } from "./api"
|
import { Api } from "./api"
|
||||||
import { ServerAuth } from "./auth"
|
import { ServerAuth } from "./auth"
|
||||||
import { handlers } from "./handlers"
|
import { handlers } from "./handlers"
|
||||||
|
|
@ -58,15 +58,24 @@ function makeRoutes<AuthError, AuthServices>(
|
||||||
sdkPlugins?: SdkPlugins.Store,
|
sdkPlugins?: SdkPlugins.Store,
|
||||||
) {
|
) {
|
||||||
const pluginRuntimeCell = PluginRuntime.makeCell()
|
const pluginRuntimeCell = PluginRuntime.makeCell()
|
||||||
const serviceLayer = AppNodeBuilder.build(
|
const replacements: LayerNode.Replacements = [
|
||||||
applicationServices,
|
[SessionExecution.node, SessionExecutionLocal.node],
|
||||||
[
|
[PluginRuntime.node, PluginRuntime.layerWithCell(pluginRuntimeCell)],
|
||||||
[SessionExecution.node, SessionExecutionLocal.node],
|
[PluginRuntime.providerNode, PluginRuntime.providerNodeWithCell(pluginRuntimeCell)],
|
||||||
[PluginRuntime.node, PluginRuntime.layerWithCell(pluginRuntimeCell)],
|
...(sdkPlugins ? [[SdkPlugins.node, SdkPlugins.layerWithStore(sdkPlugins)] as const] : []),
|
||||||
[PluginRuntime.providerNode, PluginRuntime.providerNodeWithCell(pluginRuntimeCell)],
|
]
|
||||||
...(sdkPlugins ? [[SdkPlugins.node, SdkPlugins.layerWithStore(sdkPlugins)] as const] : []),
|
// Simulation replacements are loaded via dynamic import so the simulation
|
||||||
],
|
// module is never eagerly loaded. Layer.unwrap defers both the import and
|
||||||
)
|
// the app-node build to layer-build time; when simulation is off the branch
|
||||||
|
// is byte-for-byte identical to a plain AppNodeBuilder.build call.
|
||||||
|
const serviceLayer = simulationEnabled()
|
||||||
|
? Layer.unwrap(
|
||||||
|
Effect.gen(function* () {
|
||||||
|
const { simulationReplacements } = yield* Effect.promise(() => import("./simulation"))
|
||||||
|
return AppNodeBuilder.build(applicationServices, [...replacements, ...simulationReplacements])
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
: AppNodeBuilder.build(applicationServices, replacements)
|
||||||
|
|
||||||
return HttpApiBuilder.layer(Api, { openapiPath: "/openapi.json" }).pipe(
|
return HttpApiBuilder.layer(Api, { openapiPath: "/openapi.json" }).pipe(
|
||||||
Layer.provide(handlers),
|
Layer.provide(handlers),
|
||||||
|
|
@ -79,6 +88,10 @@ function makeRoutes<AuthError, AuthServices>(
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function simulationEnabled() {
|
||||||
|
return !!process.env.OPENCODE_SIMULATION
|
||||||
|
}
|
||||||
|
|
||||||
export const routes = createRoutes()
|
export const routes = createRoutes()
|
||||||
|
|
||||||
export const webHandler = () =>
|
export const webHandler = () =>
|
||||||
|
|
|
||||||
14
packages/server/src/simulation/index.ts
Normal file
14
packages/server/src/simulation/index.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { LayerNode } from "@opencode-ai/core/effect/layer-node"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Layer replacements applied when the server is built in simulation mode.
|
||||||
|
*
|
||||||
|
* Empty for now; simulation-mode implementations will populate this with
|
||||||
|
* replacement nodes/layers that swap real services for simulated ones (e.g.
|
||||||
|
* a fake filesystem). The server merges these into the app node build when
|
||||||
|
* `OPENCODE_SIMULATION` is enabled, via a dynamic import so this module is
|
||||||
|
* never loaded eagerly.
|
||||||
|
*/
|
||||||
|
export const simulationReplacements: LayerNode.Replacements = []
|
||||||
|
|
||||||
|
export * as Simulation from "./index"
|
||||||
Loading…
Add table
Add a link
Reference in a new issue