fix(effect): add effect bridge for callback contexts (#22504)
This commit is contained in:
@@ -25,7 +25,7 @@ import { Bus } from "@/bus"
|
||||
import { TuiEvent } from "@/cli/cmd/tui/event"
|
||||
import open from "open"
|
||||
import { Effect, Exit, Layer, Option, Context, Stream } from "effect"
|
||||
import { EffectLogger } from "@/effect/logger"
|
||||
import { EffectBridge } from "@/effect/bridge"
|
||||
import { InstanceState } from "@/effect/instance-state"
|
||||
import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process"
|
||||
import * as CrossSpawnSpawner from "@/effect/cross-spawn-spawner"
|
||||
@@ -471,25 +471,24 @@ export namespace MCP {
|
||||
Effect.catch(() => Effect.succeed([] as number[])),
|
||||
)
|
||||
|
||||
function watch(s: State, name: string, client: MCPClient, timeout?: number) {
|
||||
function watch(s: State, name: string, client: MCPClient, bridge: EffectBridge.Shape, timeout?: number) {
|
||||
client.setNotificationHandler(ToolListChangedNotificationSchema, async () => {
|
||||
log.info("tools list changed notification received", { server: name })
|
||||
if (s.clients[name] !== client || s.status[name]?.status !== "connected") return
|
||||
|
||||
const listed = await Effect.runPromise(defs(name, client, timeout).pipe(Effect.provide(EffectLogger.layer)))
|
||||
const listed = await bridge.promise(defs(name, client, timeout))
|
||||
if (!listed) return
|
||||
if (s.clients[name] !== client || s.status[name]?.status !== "connected") return
|
||||
|
||||
s.defs[name] = listed
|
||||
await Effect.runPromise(
|
||||
bus.publish(ToolsChanged, { server: name }).pipe(Effect.ignore, Effect.provide(EffectLogger.layer)),
|
||||
)
|
||||
await bridge.promise(bus.publish(ToolsChanged, { server: name }).pipe(Effect.ignore))
|
||||
})
|
||||
}
|
||||
|
||||
const state = yield* InstanceState.make<State>(
|
||||
Effect.fn("MCP.state")(function* () {
|
||||
const cfg = yield* cfgSvc.get()
|
||||
const bridge = yield* EffectBridge.make()
|
||||
const config = cfg.mcp ?? {}
|
||||
const s: State = {
|
||||
status: {},
|
||||
@@ -518,7 +517,7 @@ export namespace MCP {
|
||||
if (result.mcpClient) {
|
||||
s.clients[key] = result.mcpClient
|
||||
s.defs[key] = result.defs!
|
||||
watch(s, key, result.mcpClient, mcp.timeout)
|
||||
watch(s, key, result.mcpClient, bridge, mcp.timeout)
|
||||
}
|
||||
}),
|
||||
{ concurrency: "unbounded" },
|
||||
@@ -565,11 +564,12 @@ export namespace MCP {
|
||||
listed: MCPToolDef[],
|
||||
timeout?: number,
|
||||
) {
|
||||
const bridge = yield* EffectBridge.make()
|
||||
yield* closeClient(s, name)
|
||||
s.status[name] = { status: "connected" }
|
||||
s.clients[name] = client
|
||||
s.defs[name] = listed
|
||||
watch(s, name, client, timeout)
|
||||
watch(s, name, client, bridge, timeout)
|
||||
return s.status[name]
|
||||
})
|
||||
|
||||
|
||||
Reference in New Issue
Block a user