huskies: merge 643_story_web_ui_consumer_for_the_unified_status_broadcaster
This commit is contained in:
@@ -108,7 +108,50 @@ export type WsResponse =
|
||||
/** Final signal that the /btw side question has been fully answered. */
|
||||
| { type: "side_question_done"; response: string }
|
||||
/** A single server log entry (bulk on connect, then live). */
|
||||
| { type: "log_entry"; timestamp: string; level: string; message: string };
|
||||
| { type: "log_entry"; timestamp: string; level: string; message: string }
|
||||
/** A structured pipeline status event from the status broadcaster. */
|
||||
| { type: "status_update"; event: StatusEvent };
|
||||
|
||||
/**
|
||||
* A structured pipeline status event emitted by the status broadcaster.
|
||||
*
|
||||
* The discriminant `type` field enables per-event-type rendering without
|
||||
* parsing strings. All fields from the original event are preserved so
|
||||
* future UI stories can add dedicated icons, banners, or filters.
|
||||
*/
|
||||
export type StatusEvent =
|
||||
| {
|
||||
type: "stage_transition";
|
||||
story_id: string;
|
||||
story_name: string | null;
|
||||
from_stage: string;
|
||||
to_stage: string;
|
||||
}
|
||||
| {
|
||||
type: "merge_failure";
|
||||
story_id: string;
|
||||
story_name: string | null;
|
||||
reason: string;
|
||||
}
|
||||
| {
|
||||
type: "story_blocked";
|
||||
story_id: string;
|
||||
story_name: string | null;
|
||||
reason: string;
|
||||
}
|
||||
| {
|
||||
type: "rate_limit_warning";
|
||||
story_id: string;
|
||||
story_name: string | null;
|
||||
agent_name: string;
|
||||
}
|
||||
| {
|
||||
type: "rate_limit_hard_block";
|
||||
story_id: string;
|
||||
story_name: string | null;
|
||||
agent_name: string;
|
||||
reset_at: string;
|
||||
};
|
||||
|
||||
export interface ProviderConfig {
|
||||
provider: string;
|
||||
@@ -478,6 +521,7 @@ export class ChatWebSocket {
|
||||
level: string,
|
||||
message: string,
|
||||
) => void;
|
||||
private onStatusUpdate?: (event: StatusEvent) => void;
|
||||
private onConnected?: () => void;
|
||||
private connected = false;
|
||||
private closeTimer?: number;
|
||||
@@ -573,6 +617,7 @@ export class ChatWebSocket {
|
||||
this.onSideQuestionDone?.(data.response);
|
||||
if (data.type === "log_entry")
|
||||
this.onLogEntry?.(data.timestamp, data.level, data.message);
|
||||
if (data.type === "status_update") this.onStatusUpdate?.(data.event);
|
||||
if (data.type === "pong") {
|
||||
window.clearTimeout(this.heartbeatTimeout);
|
||||
this.heartbeatTimeout = undefined;
|
||||
@@ -630,6 +675,7 @@ export class ChatWebSocket {
|
||||
onSideQuestionToken?: (content: string) => void;
|
||||
onSideQuestionDone?: (response: string) => void;
|
||||
onLogEntry?: (timestamp: string, level: string, message: string) => void;
|
||||
onStatusUpdate?: (event: StatusEvent) => void;
|
||||
onConnected?: () => void;
|
||||
},
|
||||
wsPath = DEFAULT_WS_PATH,
|
||||
@@ -650,6 +696,7 @@ export class ChatWebSocket {
|
||||
this.onSideQuestionToken = handlers.onSideQuestionToken;
|
||||
this.onSideQuestionDone = handlers.onSideQuestionDone;
|
||||
this.onLogEntry = handlers.onLogEntry;
|
||||
this.onStatusUpdate = handlers.onStatusUpdate;
|
||||
this.onConnected = handlers.onConnected;
|
||||
this.wsPath = wsPath;
|
||||
this.shouldReconnect = true;
|
||||
|
||||
Reference in New Issue
Block a user