fix(sidechat): read the transcript through the plugin's own events route
DSH 0.1.2-alpha.1 removed the client `ctx.connection.api` face (Remote gateway migration), so every Side Chat transcript poll (`sessions.history`) threw TypeError into the view's catch and was swallowed — the tab rendered an empty transcript forever, silently (no console error, so the mount lane never caught it). The successor APIs are not a drop-in either: session/follow|page reject plain session addresses for origin:'subagent' logs (agent-busy fence) and paging cannot read past the current cursor. Move the transcript to the plugin's own wire — one transport for every DSH generation: - new `sidechat.events` route: live threads read the in-memory `agent.session.events`; cold threads read `sessionPersistence.inspect` (both seams exist since 0.1.0-rc.8; alpha.1's inspect returns the expanded logical log, never the packed chunk-row encoding). The inherited seed is cut host-side (`threadOwnLogEvents`), polls ride an `afterSeq` delta, and the response is tail-capped at 8000 events (the old client walk ceiling). - SideChatView.fetchThread is single-path; collectOwnEvents (the client walk) is gone, and so are the ctx.connection mirror and inject entry (no consumer left). - transcriptRows keeps re-cutting at session/end-seed as defense in depth. Verification: - unit: sidechat.events route (seed cut, afterSeq delta + never resurrecting the seed, cap, cold/live sources, 404/503/bad-request), full suite 1104 passed; typecheck and build (purity gate) green. - mount e2e vs a real dsh-v0.1.2-alpha.1 source build: 14/14, including the Side Chat tab sweep polling sidechat.events (performance resource assertion) and live + post-dispose (persisted) route reads. - mount e2e vs PATH dsh 0.1.0-rc.8: 14/14 (no regression).
This commit is contained in:
@@ -304,39 +304,6 @@ export interface SidebarSessionPersistenceService {
|
||||
}>
|
||||
}
|
||||
|
||||
/** RPC result slot mirror (`RpcResult<T>` on the wire). */
|
||||
export type SidebarRpcResult<T> = { ok: true; value: T } | { ok: false; error: { code: string; message: string } }
|
||||
|
||||
/** Unary response mirror (`RpcResponse<T>` on the wire). */
|
||||
export interface SidebarRpcResponse<T> {
|
||||
rpcId: unknown
|
||||
result: SidebarRpcResult<T>
|
||||
}
|
||||
|
||||
/** The generic session-history RPC face the Side Chat transcript polls
|
||||
* (subagent.history verifies subagent-catalog membership, which our custom
|
||||
* side-thread children do not have — the generic session.history reads any
|
||||
* durable log directly). */
|
||||
export interface SidebarSessionHistoryRpc {
|
||||
history(
|
||||
payload: { sessionId: string; beforeSeq?: number; maxMessages?: number },
|
||||
signal?: AbortSignal,
|
||||
): Promise<SidebarRpcResponse<{ events: SidebarHistoryEntry[]; hasMore: boolean }>>
|
||||
}
|
||||
|
||||
/** The wire face the Subagent activity summary needs (subset of `ctx.connection`). */
|
||||
export interface SidebarConnectionHandle {
|
||||
api: {
|
||||
sessions: SidebarSessionHistoryRpc
|
||||
subagents: {
|
||||
history(
|
||||
payload: SidebarSubagentAddress & { beforeSeq?: number; maxMessages?: number },
|
||||
signal?: AbortSignal,
|
||||
): Promise<SidebarRpcResponse<{ events: SidebarHistoryEntry[]; hasMore: boolean }>>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** The client session list snapshot the sidebar subscribes to. */
|
||||
export interface SidebarSessionList {
|
||||
current: string | undefined
|
||||
@@ -527,8 +494,6 @@ export interface SidebarContextShape {
|
||||
webServer: SidebarWebServer
|
||||
/** The session store (host `.get`) and the client list feed (`.list`) faces. */
|
||||
sessions: SidebarSessionStore & SidebarSessionsService
|
||||
/** The wire handle the Side Chat transcript polls through. */
|
||||
connection: SidebarConnectionHandle
|
||||
/** The web runtime trust list (bind-derived). */
|
||||
webRuntime: SidebarWebRuntime
|
||||
/** The client slot registry (register/inject). */
|
||||
|
||||
Reference in New Issue
Block a user