mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-08-28 19:11:03 +08:00
fix(cli): keep location map scoped to listener
This commit is contained in:
@@ -67,12 +67,10 @@ import { ProjectCopy } from "@opencode-ai/core/project/copy" // kilocode_change
|
||||
import { MoveSession } from "@opencode-ai/core/control-plane/move-session" // kilocode_change
|
||||
import { PtyTicket } from "@opencode-ai/core/pty/ticket" // kilocode_change
|
||||
import { Pty } from "@opencode-ai/core/pty" // kilocode_change
|
||||
import { buildLocationServiceMap, LocationServiceMap } from "@opencode-ai/core/location-services" // kilocode_change
|
||||
|
||||
// kilocode_change start - retain Kilo runtime services in the upstream node graph
|
||||
const memory = LayerNode.make({ service: MemoryService.Service, layer: MemoryService.layer, deps: [] })
|
||||
const kilo = LayerNode.group([Credential.node, ModelCache.node, AgentManager.node, Notebook.node, memory])
|
||||
const locationServiceMap = buildLocationServiceMap() // kilocode_change - bind fallback consumers to one process-wide map
|
||||
// kilocode_change end
|
||||
|
||||
export const AppLayer = AppNodeBuilderV1.build(
|
||||
@@ -134,10 +132,8 @@ export const AppLayer = AppNodeBuilderV1.build(
|
||||
MoveSession.node,
|
||||
PtyTicket.node,
|
||||
Pty.shutdownNode, // kilocode_change
|
||||
LocationServiceMap.node, // kilocode_change - expose the process-wide location cache to listeners
|
||||
// kilocode_change end
|
||||
]),
|
||||
[[LocationServiceMap.node, locationServiceMap]], // kilocode_change
|
||||
).pipe(Layer.provideMerge(AppNodeBuilderV1.build(Ripgrep.node)), Layer.provideMerge(Observability.layer))
|
||||
|
||||
const rt = ManagedRuntime.make(AppLayer, { memoMap })
|
||||
|
||||
@@ -337,7 +337,7 @@ export function createRoutes(
|
||||
),
|
||||
Layer.provide(locationServiceMapV2),
|
||||
|
||||
Layer.provide(AppNodeBuilderV1.build(app, [[LocationServiceMap.node, locationServiceMapV2]])), // kilocode_change
|
||||
Layer.provide(AppNodeBuilderV1.build(app)),
|
||||
// Must stay last: layers provided later in this pipe build beneath earlier ones,
|
||||
// so Observability must come after every service graph. Otherwise eagerly forked
|
||||
// fibers (e.g. the ModelsDev background refresh) capture Effect's default stdout
|
||||
@@ -348,9 +348,7 @@ export function createRoutes(
|
||||
|
||||
// kilocode_change start - keep listener routes local while application services come from AppRuntime
|
||||
export function createListenerRoutes(corsOptions?: CorsOptions) {
|
||||
// Re-export AppRuntime's process-wide map through listener-local graphs instead of
|
||||
// materializing another full catalog and native file index for every worktree.
|
||||
const locationServiceMapV2 = Layer.effect(LocationServiceMap.Service, LocationServiceMap.Service)
|
||||
const locationServiceMapV2 = buildLocationServiceMap()
|
||||
|
||||
return Layer.mergeAll(
|
||||
rootApiRoutes,
|
||||
@@ -366,8 +364,11 @@ export function createListenerRoutes(corsOptions?: CorsOptions) {
|
||||
// satisfied when the layer is built, not at request time, so the listener needs the same chain
|
||||
// createRoutes uses.
|
||||
//
|
||||
// SessionV2 remains listener-local because it uses SessionExecutionLocal. Its location map is
|
||||
// inherited from AppRuntime so every server graph shares one cache.
|
||||
// These builds sit inside KiloListener's Layer.fresh boundary, so each one self-provides its own
|
||||
// dependency subtree rather than resolving AppRuntime's. That is deliberate: SessionV2 is bound
|
||||
// to this listener's LocationServiceMap and to SessionExecutionLocal, so it cannot be the
|
||||
// process-wide instance. Everything the graph does not rebind (the nodes listed in AppLayer)
|
||||
// still comes from AppRuntime, and the scope teardown releases the rest.
|
||||
Layer.provide(sessionLocationLayer),
|
||||
Layer.provide(locationLayer),
|
||||
Layer.provide(PtyEnvironment.layer),
|
||||
|
||||
@@ -20,16 +20,13 @@ describe("shared location service map", () => {
|
||||
}
|
||||
})
|
||||
|
||||
test("server app graph receives the listener location map", () => {
|
||||
test("listener owns its location map scope", () => {
|
||||
expect(source("server/routes/instance/httpapi/server.ts")).toContain(
|
||||
"const locationServiceMapV2 = buildLocationServiceMap()",
|
||||
)
|
||||
expect(source("server/routes/instance/httpapi/server.ts")).not.toContain(
|
||||
"AppNodeBuilderV1.build(app, [[LocationServiceMap.node, locationServiceMapV2]])",
|
||||
)
|
||||
})
|
||||
|
||||
test("listener inherits the process-wide location map", () => {
|
||||
expect(source("server/routes/instance/httpapi/server.ts")).toContain(
|
||||
"Layer.effect(LocationServiceMap.Service, LocationServiceMap.Service)",
|
||||
)
|
||||
expect(source("effect/app-runtime.ts")).toContain("LocationServiceMap.node")
|
||||
expect(source("effect/app-runtime.ts")).not.toContain("LocationServiceMap.node")
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user