feat(tui): refresh agents after update events

This commit is contained in:
Dax Raad 2026-06-29 18:52:00 -04:00
commit 02cb350880
17 changed files with 576 additions and 30 deletions

View file

@ -1,6 +1,7 @@
import { describe, expect } from "bun:test"
import { Effect, Exit, Scope } from "effect"
import { Effect, Exit, Fiber, Layer, Scope, Stream } from "effect"
import { AgentV2 } from "@opencode-ai/core/agent"
import { EventV2 } from "@opencode-ai/core/event"
import { Location } from "@opencode-ai/core/location"
import { AgentPlugin } from "@opencode-ai/core/plugin/agent"
import { AbsolutePath } from "@opencode-ai/core/schema"
@ -8,9 +9,32 @@ import { location } from "./fixture/location"
import { testEffect } from "./lib/effect"
import { agentHost, host } from "./plugin/host"
const it = testEffect(AgentV2.locationLayer)
const testLocation = location({ directory: AbsolutePath.make("/project") })
const locationLayer = Layer.succeed(Location.Service, Location.Service.of(testLocation))
const it = testEffect(
AgentV2.locationLayer.pipe(
Layer.provideMerge(EventV2.defaultLayer),
Layer.provideMerge(locationLayer),
),
)
describe("AgentV2", () => {
it.effect("publishes an updated event after agent changes", () =>
Effect.gen(function* () {
const agent = yield* AgentV2.Service
const events = yield* EventV2.Service
const updated = yield* events
.subscribe(AgentV2.Event.Updated)
.pipe(Stream.take(1), Stream.runCollect, Effect.forkScoped)
yield* Effect.yieldNow
yield* agent.transform((editor) => editor.update(AgentV2.ID.make("reviewer"), () => {}))
expect(yield* Fiber.join(updated)).toMatchObject([{ location: { directory: testLocation.directory } }])
}),
)
it.effect("starts without agents", () =>
Effect.gen(function* () {
const agent = yield* AgentV2.Service

View file

@ -5,6 +5,7 @@ import { Effect, Layer, Schema } from "effect"
import { AgentV2 } from "@opencode-ai/core/agent"
import { Config } from "@opencode-ai/core/config"
import { ConfigAgentPlugin } from "@opencode-ai/core/config/plugin/agent"
import { EventV2 } from "@opencode-ai/core/event"
import { FSUtil } from "@opencode-ai/core/fs-util"
import { PermissionV2 } from "@opencode-ai/core/permission"
import { AbsolutePath } from "@opencode-ai/core/schema"
@ -12,7 +13,9 @@ import { tmpdir } from "../fixture/tmpdir"
import { testEffect } from "../lib/effect"
import { agentHost, host } from "../plugin/host"
const it = testEffect(Layer.mergeAll(AgentV2.locationLayer, FSUtil.defaultLayer))
const it = testEffect(
Layer.mergeAll(AgentV2.locationLayer.pipe(Layer.provideMerge(EventV2.defaultLayer)), FSUtil.defaultLayer),
)
const decode = Schema.decodeUnknownSync(Config.Info)
describe("ConfigAgentPlugin.Plugin", () => {

View file

@ -59,7 +59,7 @@ const permission = Layer.succeed(
}),
)
const registry = ToolRegistry.defaultLayer.pipe(Layer.provide(permission))
const agents = AgentV2.layer
const agents = AgentV2.layer.pipe(Layer.provide(EventV2.defaultLayer))
const model = OpenAIChat.route
.with({
endpoint: { baseURL: "https://api.openai.com/v1" },

View file

@ -129,7 +129,7 @@ const registry = ToolRegistry.layer.pipe(
Layer.provide(applications),
Layer.provide(ToolOutputStore.defaultLayer),
)
const agents = AgentV2.layer
const agents = AgentV2.layer.pipe(Layer.provide(EventV2.defaultLayer))
const echo = Layer.effectDiscard(
ToolRegistry.Service.use((registry) =>
registry.register({