feat(webui): add tabbed pane workbench (#5322)

This commit is contained in:
chengyongru
2026-08-12 14:45:12 +08:00
committed by GitHub
parent 1656664a47
commit 4b5319b760
38 changed files with 5706 additions and 527 deletions
+20
View File
@@ -73,6 +73,7 @@ type SessionUpdateHandler = (
scope?: SessionUpdateScope,
workspaceScope?: WorkspaceScopePayload,
) => void;
type SidebarStateUpdateHandler = (state: SidebarStatePayload) => void;
type RunStatusHandler = (chatId: string, startedAt: number | null) => void;
/** Structured errors surfaced to the UI.
@@ -178,6 +179,7 @@ export class NanobotClient {
private statusHandlers = new Set<StatusHandler>();
private runtimeModelHandlers = new Set<RuntimeModelHandler>();
private sessionUpdateHandlers = new Set<SessionUpdateHandler>();
private sidebarStateUpdateHandlers = new Set<SidebarStateUpdateHandler>();
private runStatusHandlers = new Set<RunStatusHandler>();
private errorHandlers = new Set<ErrorHandler>();
// chat_id -> handlers listening on it
@@ -275,6 +277,13 @@ export class NanobotClient {
};
}
onSidebarStateUpdate(handler: SidebarStateUpdateHandler): Unsubscribe {
this.sidebarStateUpdateHandlers.add(handler);
return () => {
this.sidebarStateUpdateHandlers.delete(handler);
};
}
onRunStatus(handler: RunStatusHandler): Unsubscribe {
this.runStatusHandlers.add(handler);
for (const [chatId, startedAt] of this.runStartedAtByChatId) {
@@ -1149,6 +1158,11 @@ export class NanobotClient {
return;
}
if (parsed.event === "sidebar_state_updated") {
this.emitSidebarStateUpdate(parsed.state);
return;
}
if (parsed.event === "error" && parsed.detail === "workspace_scope_rejected") {
this.emitError({
kind: "workspace_scope_rejected",
@@ -1198,6 +1212,12 @@ export class NanobotClient {
}
}
private emitSidebarStateUpdate(state: SidebarStatePayload): void {
for (const handler of this.sidebarStateUpdateHandlers) {
handler(state);
}
}
private emitRunStatus(chatId: string, startedAt: number | null): void {
for (const handler of this.runStatusHandlers) {
handler(chatId, startedAt);