diff --git a/packages/opencode/src/server/projectors.ts b/packages/opencode/src/server/projectors.ts index c5fb2420a0..1d250d4dec 100644 --- a/packages/opencode/src/server/projectors.ts +++ b/packages/opencode/src/server/projectors.ts @@ -6,6 +6,7 @@ import { Database } from "@/storage/db" import { eq } from "drizzle-orm" export function initProjectors() { + console.log("initProjectors") SyncEvent.init({ projectors: sessionProjectors, convertEvent: (type, data) => { diff --git a/packages/opencode/src/server/routes/instance/httpapi/api.ts b/packages/opencode/src/server/routes/instance/httpapi/api.ts index eff336b3c6..c1779ab921 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/api.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/api.ts @@ -1,3 +1,6 @@ +import { initProjectors } from "@/server/projectors" +initProjectors() + import { Schema } from "effect" import { HttpApi } from "effect/unstable/httpapi" import { BusEvent } from "@/bus/bus-event" diff --git a/packages/opencode/src/server/routes/instance/httpapi/groups/global.ts b/packages/opencode/src/server/routes/instance/httpapi/groups/global.ts index 5b8a44d2cf..75441b4ca4 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/groups/global.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/groups/global.ts @@ -1,7 +1,6 @@ import { Config } from "@/config/config" import { BusEvent } from "@/bus/bus-event" import { SyncEvent } from "@/sync" -import "@/event-v2-bridge" import "@/server/event" import { Schema } from "effect" import { HttpApi, HttpApiEndpoint, HttpApiError, HttpApiGroup, OpenApi } from "effect/unstable/httpapi" diff --git a/packages/opencode/src/server/server.ts b/packages/opencode/src/server/server.ts index b7a46918b2..e787006271 100644 --- a/packages/opencode/src/server/server.ts +++ b/packages/opencode/src/server/server.ts @@ -5,7 +5,6 @@ import { HttpRouter, HttpServer } from "effect/unstable/http" import { OpenApi } from "effect/unstable/httpapi" import { createServer } from "node:http" import { MDNS } from "./mdns" -import { initProjectors } from "./projectors" import { HttpApiApp } from "./routes/instance/httpapi/server" import { disposeMiddleware } from "./routes/instance/httpapi/lifecycle" import { WebSocketTracker } from "./routes/instance/httpapi/websocket-tracker" @@ -16,8 +15,6 @@ import { lazy } from "@/util/lazy" // @ts-ignore This global is needed to prevent ai-sdk from logging warnings to stdout https://github.com/vercel/ai/blob/2dc67e0ef538307f21368db32d5a12345d98831b/packages/ai/src/logger/log-warnings.ts#L85 globalThis.AI_SDK_LOG_WARNINGS = false -initProjectors() - const log = Log.create({ service: "server" }) export type Listener = { diff --git a/packages/opencode/src/sync/index.ts b/packages/opencode/src/sync/index.ts index d2cc1a1c5f..bdc319e282 100644 --- a/packages/opencode/src/sync/index.ts +++ b/packages/opencode/src/sync/index.ts @@ -226,9 +226,6 @@ export function reset() { } export function init(input: { projectors: Array<[Definition, ProjectorFunc]>; convertEvent?: ConvertEvent }) { - for (const [def] of input.projectors) { - register(def) - } projectors = new Map(input.projectors) // Install all the latest event defs to the bus. We only ever emit @@ -236,8 +233,8 @@ export function init(input: { projectors: Array<[Definition, ProjectorFunc]>; co // replaying. Replaying does not go through the bus, and it // simplifies the bus to only use unversioned latest events for (let [type, version] of versions.entries()) { + console.log(type) let def = registry.get(versionedType(type, version))! - BusEvent.define(def.type, def.properties) } @@ -286,7 +283,6 @@ export function project( def: Def, func: (db: Database.TxOrDb, data: Event["data"], event: Event) => void, ): [Definition, ProjectorFunc] { - register(def) return [def, func as ProjectorFunc] } @@ -393,7 +389,7 @@ export function effectPayloads() { name: EffectSchema.Literal(versionedType(definition.type, definition.version!)), id: EffectSchema.String, seq: EffectSchema.Finite, - aggregateID: EffectSchema.String, + aggregateID: EffectSchema.Literal(definition.aggregate!), data: definition.data, }).annotate({ identifier: `SyncEvent.${definition.type}` }), ) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 40ad4f5a6c..a0cc527471 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -5,6 +5,12 @@ export type ClientOptions = { } export type Event = + | EventTuiPromptAppend + | EventTuiCommandExecute + | EventTuiToastShow1 + | EventTuiSessionSelect + | EventServerConnected + | EventGlobalDisposed | EventServerInstanceDisposed | EventFileEdited | EventFileWatcherUpdated @@ -21,10 +27,6 @@ export type Event = | EventTodoUpdated | EventSessionStatus | EventSessionIdle - | EventTuiPromptAppend - | EventTuiCommandExecute - | EventTuiToastShow1 - | EventTuiSessionSelect | EventMcpToolsChanged | EventMcpBrowserOpenFailed | EventCommandExecuted @@ -42,8 +44,13 @@ export type Event = | EventPtyDeleted | EventInstallationUpdated | EventInstallationUpdateAvailable - | EventServerConnected - | EventGlobalDisposed + | EventMessageUpdated + | EventMessageRemoved + | EventMessagePartUpdated + | EventMessagePartRemoved + | EventSessionCreated + | EventSessionUpdated + | EventSessionDeleted | EventCatalogModelUpdated | EventSessionNextAgentSwitched | EventSessionNextModelSwitched @@ -97,6 +104,61 @@ export type WellKnownAuth = { export type Auth = OAuth | ApiAuth | WellKnownAuth +export type EventTuiPromptAppend = { + id: string + type: "tui.prompt.append" + properties: { + text: string + } +} + +export type EventTuiCommandExecute = { + id: string + type: "tui.command.execute" + properties: { + command: + | "session.list" + | "session.new" + | "session.share" + | "session.interrupt" + | "session.compact" + | "session.page.up" + | "session.page.down" + | "session.line.up" + | "session.line.down" + | "session.half.page.up" + | "session.half.page.down" + | "session.first" + | "session.last" + | "prompt.clear" + | "prompt.submit" + | "agent.cycle" + | string + } +} + +export type EventTuiToastShow = { + id: string + type: "tui.toast.show" + properties: { + title?: string + message: string + variant: "info" | "success" | "warning" | "error" + duration?: number + } +} + +export type EventTuiSessionSelect = { + id: string + type: "tui.session.select" + properties: { + /** + * Session ID to navigate to + */ + sessionID: string + } +} + export type PermissionRequest = { id: string sessionID: string @@ -274,61 +336,6 @@ export type SessionStatus = type: "busy" } -export type EventTuiPromptAppend = { - id: string - type: "tui.prompt.append" - properties: { - text: string - } -} - -export type EventTuiCommandExecute = { - id: string - type: "tui.command.execute" - properties: { - command: - | "session.list" - | "session.new" - | "session.share" - | "session.interrupt" - | "session.compact" - | "session.page.up" - | "session.page.down" - | "session.line.up" - | "session.line.down" - | "session.half.page.up" - | "session.half.page.down" - | "session.first" - | "session.last" - | "prompt.clear" - | "prompt.submit" - | "agent.cycle" - | string - } -} - -export type EventTuiToastShow = { - id: string - type: "tui.toast.show" - properties: { - title?: string - message: string - variant: "info" | "success" | "warning" | "error" - duration?: number - } -} - -export type EventTuiSessionSelect = { - id: string - type: "tui.session.select" - properties: { - /** - * Session ID to navigate to - */ - sessionID: string - } -} - export type Project = { id: string worktree: string @@ -783,6 +790,12 @@ export type GlobalEvent = { project?: string workspace?: string payload: + | EventTuiPromptAppend + | EventTuiCommandExecute + | EventTuiToastShow + | EventTuiSessionSelect + | EventServerConnected + | EventGlobalDisposed | EventServerInstanceDisposed | EventFileEdited | EventFileWatcherUpdated @@ -799,10 +812,6 @@ export type GlobalEvent = { | EventTodoUpdated | EventSessionStatus | EventSessionIdle - | EventTuiPromptAppend - | EventTuiCommandExecute - | EventTuiToastShow - | EventTuiSessionSelect | EventMcpToolsChanged | EventMcpBrowserOpenFailed | EventCommandExecuted @@ -820,8 +829,6 @@ export type GlobalEvent = { | EventPtyDeleted | EventInstallationUpdated | EventInstallationUpdateAvailable - | EventServerConnected - | EventGlobalDisposed | EventCatalogModelUpdated | EventSessionNextAgentSwitched | EventSessionNextModelSwitched @@ -868,20 +875,20 @@ export type GlobalEvent = { | SyncEventSessionNextTextStarted | SyncEventSessionNextTextDelta | SyncEventSessionNextTextEnded + | SyncEventSessionNextReasoningStarted + | SyncEventSessionNextReasoningDelta + | SyncEventSessionNextReasoningEnded | SyncEventSessionNextToolInputStarted | SyncEventSessionNextToolInputDelta | SyncEventSessionNextToolInputEnded | SyncEventSessionNextToolCalled + | SyncEventSessionNextToolProgress | SyncEventSessionNextToolSuccess | SyncEventSessionNextToolFailed - | SyncEventSessionNextReasoningStarted - | SyncEventSessionNextReasoningDelta - | SyncEventSessionNextReasoningEnded | SyncEventSessionNextRetried | SyncEventSessionNextCompactionStarted | SyncEventSessionNextCompactionDelta | SyncEventSessionNextCompactionEnded - | SyncEventSessionNextToolProgress } /** @@ -2169,6 +2176,47 @@ export type SyncEventSessionNextTextEnded = { } } +export type SyncEventSessionNextReasoningStarted = { + type: "sync" + name: "session.next.reasoning.started.1" + id: string + seq: number + aggregateID: "sessionID" + data: { + timestamp: number + sessionID: string + reasoningID: string + } +} + +export type SyncEventSessionNextReasoningDelta = { + type: "sync" + name: "session.next.reasoning.delta.1" + id: string + seq: number + aggregateID: "sessionID" + data: { + timestamp: number + sessionID: string + reasoningID: string + delta: string + } +} + +export type SyncEventSessionNextReasoningEnded = { + type: "sync" + name: "session.next.reasoning.ended.1" + id: string + seq: number + aggregateID: "sessionID" + data: { + timestamp: number + sessionID: string + reasoningID: string + text: string + } +} + export type SyncEventSessionNextToolInputStarted = { type: "sync" name: "session.next.tool.input.started.1" @@ -2234,6 +2282,23 @@ export type SyncEventSessionNextToolCalled = { } } +export type SyncEventSessionNextToolProgress = { + type: "sync" + name: "session.next.tool.progress.1" + id: string + seq: number + aggregateID: "sessionID" + data: { + timestamp: number + sessionID: string + callID: string + structured: { + [key: string]: unknown + } + content: Array + } +} + export type SyncEventSessionNextToolSuccess = { type: "sync" name: "session.next.tool.success.1" @@ -2277,47 +2342,6 @@ export type SyncEventSessionNextToolFailed = { } } -export type SyncEventSessionNextReasoningStarted = { - type: "sync" - name: "session.next.reasoning.started.1" - id: string - seq: number - aggregateID: "sessionID" - data: { - timestamp: number - sessionID: string - reasoningID: string - } -} - -export type SyncEventSessionNextReasoningDelta = { - type: "sync" - name: "session.next.reasoning.delta.1" - id: string - seq: number - aggregateID: "sessionID" - data: { - timestamp: number - sessionID: string - reasoningID: string - delta: string - } -} - -export type SyncEventSessionNextReasoningEnded = { - type: "sync" - name: "session.next.reasoning.ended.1" - id: string - seq: number - aggregateID: "sessionID" - data: { - timestamp: number - sessionID: string - reasoningID: string - text: string - } -} - export type SyncEventSessionNextRetried = { type: "sync" name: "session.next.retried.1" @@ -2372,20 +2396,19 @@ export type SyncEventSessionNextCompactionEnded = { } } -export type SyncEventSessionNextToolProgress = { - type: "sync" - name: "session.next.tool.progress.1" +export type EventServerConnected = { id: string - seq: number - aggregateID: string - data: { - timestamp: number - sessionID: string - callID: string - structured: { - [key: string]: unknown - } - content: Array + type: "server.connected" + properties: { + [key: string]: unknown + } +} + +export type EventGlobalDisposed = { + id: string + type: "global.disposed" + properties: { + [key: string]: unknown } } @@ -2669,22 +2692,6 @@ export type EventInstallationUpdateAvailable = { } } -export type EventServerConnected = { - id: string - type: "server.connected" - properties: { - [key: string]: unknown - } -} - -export type EventGlobalDisposed = { - id: string - type: "global.disposed" - properties: { - [key: string]: unknown - } -} - export type ModelV2Info = { id: string apiID: string @@ -3485,6 +3492,71 @@ export type EventTuiToastShow1 = { } } +export type EventMessageUpdated = { + id: string + type: "message.updated" + properties: { + sessionID: string + info: Message + } +} + +export type EventMessageRemoved = { + id: string + type: "message.removed" + properties: { + sessionID: string + messageID: string + } +} + +export type EventMessagePartUpdated = { + id: string + type: "message.part.updated" + properties: { + sessionID: string + part: Part + time: number + } +} + +export type EventMessagePartRemoved = { + id: string + type: "message.part.removed" + properties: { + sessionID: string + messageID: string + partID: string + } +} + +export type EventSessionCreated = { + id: string + type: "session.created" + properties: { + sessionID: string + info: Session + } +} + +export type EventSessionUpdated = { + id: string + type: "session.updated" + properties: { + sessionID: string + info: Session + } +} + +export type EventSessionDeleted = { + id: string + type: "session.deleted" + properties: { + sessionID: string + info: Session + } +} + export type ModelV2Info1 = { id: string apiID: string