Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import {
fetchEventSource,
type EventSourceMessage
} from "@microsoft/fetch-event-source";
import { useEffect, useRef, useState } from "react";
import { useState } from "react";
import { useNavigate } from "react-router";
import { useAgenticDispatch } from "../../../../containers/Agentic/hooks";
import {
useGetIncidentAgentEventsQuery,
useSendMessageToIncidentCreationChatMutation
useSendMessageToIncidentCreationChatMutation,
useStartIncidentCreationChatMutation
} from "../../../../redux/services/digma";
import type { IncidentAgentEvent } from "../../../../redux/services/types";
import { setIsCreateIncidentChatOpen } from "../../../../redux/slices/incidentsSlice";
import { isString } from "../../../../typeGuards/isString";
import { sendUserActionTrackingEvent } from "../../../../utils/actions/sendUserActionTrackingEvent";
import { CancelConfirmation } from "../../../common/CancelConfirmation";
import { trackingEvents } from "../../tracking";
Expand All @@ -20,22 +16,22 @@ import * as s from "./styles";
const AGENT_ID = "incident_entry";
const PROMPT_FONT_SIZE = 14; // in pixels
const REFRESH_INTERVAL = 10 * 1000; // in milliseconds
const REFRESH_INTERVAL_DURING_STREAMING = 3 * 1000; // in milliseconds

export const CreateIncidentChatOverlay = () => {
const [incidentId, setIncidentId] = useState<string>();
const [
isCloseConfirmationDialogVisible,
setIsCloseConfirmationDialogVisible
] = useState(false);
const [isStartMessageSending, setIsStartMessageSending] = useState(false);
const abortControllerRef = useRef<AbortController | null>(null);
const [accumulatedData, setAccumulatedData] =
useState<IncidentAgentEvent[]>();
const navigate = useNavigate();

const dispatch = useAgenticDispatch();

const [sendStartMessage, { isLoading: isStartMessageSending }] =
useStartIncidentCreationChatMutation();

const [sendMessage, { isLoading: isSubsequentMessageSending }] =
useSendMessageToIncidentCreationChatMutation();

Expand All @@ -48,9 +44,7 @@ export const CreateIncidentChatOverlay = () => {
},
{
skip: !incidentId,
pollingInterval: isMessageSending
? REFRESH_INTERVAL_DURING_STREAMING
: REFRESH_INTERVAL
pollingInterval: REFRESH_INTERVAL
}
);

Expand All @@ -67,93 +61,12 @@ export const CreateIncidentChatOverlay = () => {
mcp_name: null
}
]);
// Stop any existing connection
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}

abortControllerRef.current = new AbortController();

setIsStartMessageSending(true);
void fetchEventSource(
`${
isString(window.digmaApiProxyPrefix)
? window.digmaApiProxyPrefix
: "/api/"
}Agentic/incident-entry`,
{
method: "POST",
credentials: "same-origin",
headers: {
"Content-Type": "application/json"
},
signal: abortControllerRef.current.signal,
body: JSON.stringify({
text
}),
openWhenHidden: true,
onopen: (response: Response) => {
if (response.ok) {
setIncidentId(
response.headers.get("agentic-conversation-id") ?? ""
);
// eslint-disable-next-line no-console
console.log(
`[${new Date().toISOString()}] Got conversation ID:`,
response.headers.get("agentic-conversation-id") ?? ""
);
setIsStartMessageSending(false);
return Promise.resolve();
} else {
setIsStartMessageSending(false);
return Promise.reject(
new Error(`HTTP ${response.status}: ${response.statusText}`)
);
}
},
onmessage: (message: EventSourceMessage) => {
// eslint-disable-next-line no-console
console.log(
`[${new Date().toISOString()}] Received message:`,
message
);
// if (message.data) {
// try {
// const parsedData = JSON.parse(
// message.data
// ) as IncidentAgentEvent;
// if (["human", "token"].includes(parsedData.type)) {
// setAccumulatedData((prev) =>
// prev ? [...prev, parsedData] : [parsedData]
// );
// }
// if (parsedData.type === "input_user_required") {
// setIsStartMessageSending(false);
// }
// } catch (error) {
// // eslint-disable-next-line no-console
// console.error("Error parsing message data:", error);
// }
// }
},
onerror: (err: unknown) => {
abortControllerRef.current = null;
setIsStartMessageSending(false);
let errorMessage = "Unknown error starting incident creation chat";
if (err instanceof Error) {
errorMessage = err.message;
}

// eslint-disable-next-line no-console
console.error(errorMessage);

throw new Error(errorMessage); // Rethrow the error to avoid retrying
},
onclose: () => {
abortControllerRef.current = null;
}
}
);
void sendStartMessage({ data: { text } })
.unwrap()
.then((response) => {
setIncidentId(response.conversation_id);
});
} else {
// Send subsequent messages to the incident creation chat
void sendMessage({
Expand Down Expand Up @@ -188,14 +101,6 @@ export const CreateIncidentChatOverlay = () => {
dispatch(setIsCreateIncidentChatOpen(false));
};

useEffect(() => {
return () => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
}
};
}, []);

return (
<>
<s.StyledOverlay>
Expand Down
18 changes: 16 additions & 2 deletions src/redux/services/digma.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ import type {
SetMetricsReportDataPayload,
SetServiceEndpointsPayload,
SetServiceEnvironmentsPayload,
StartIncidentCreationChatPayload,
StartIncidentCreationChatResponse,
TestMCPServerPayload,
TestMCPServerResponse,
UndismissErrorPayload,
Expand Down Expand Up @@ -663,12 +665,23 @@ export const digmaApi = createApi({
}),
invalidatesTags: ["IncidentAgentChatEvent"]
}),
startIncidentCreationChat: builder.mutation<
StartIncidentCreationChatResponse,
StartIncidentCreationChatPayload
>({
query: ({ data }) => ({
url: `Agentic/manual-incident`,
method: "POST",
body: data
}),
invalidatesTags: ["IncidentEntryAgentChatEvent"]
}),
sendMessageToIncidentCreationChat: builder.mutation<
unknown, // text/event-stream
void,
SendMessageToIncidentCreationChatPayload
>({
query: ({ incidentId, data }) => ({
url: `Agentic/incident-entry/${window.encodeURIComponent(incidentId)}`,
url: `Agentic/manual-incident/${window.encodeURIComponent(incidentId)}`,
method: "POST",
body: data
}),
Expand Down Expand Up @@ -845,6 +858,7 @@ export const {
useGetIncidentAgentEventsQuery,
useGetIncidentAgentChatEventsQuery,
useSendMessageToIncidentAgentChatMutation,
useStartIncidentCreationChatMutation,
useSendMessageToIncidentCreationChatMutation,
useGetIncidentAgentDirectivesQuery,
useDeleteIncidentAgentDirectiveMutation,
Expand Down
8 changes: 8 additions & 0 deletions src/redux/services/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1258,6 +1258,14 @@ export interface SendMessageToIncidentAgentChatPayload {
data: { text: string };
}

export interface StartIncidentCreationChatPayload {
data: { text: string };
}

export interface StartIncidentCreationChatResponse {
conversation_id: string;
}

export interface SendMessageToIncidentCreationChatPayload {
incidentId: string;
data: { text: string };
Expand Down
Loading