@hawtio/ai-plugin 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -49,17 +49,19 @@ var init_ai_model = __esm({
49
49
  { id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", tool: true, provider: "anthropic" },
50
50
  { id: "claude-haiku-4-5", name: "Claude Haiku 4.5", tool: true, provider: "anthropic" },
51
51
  // Google Gemini models
52
- { id: "gemini-2.5-flash", name: "Gemini 2.5 Flash", tool: true, provider: "google-genai" },
53
- { id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash-Lite", tool: true, provider: "google-genai" },
54
- { id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", tool: true, provider: "google-genai" },
52
+ { id: "gemini-3.5-flash", name: "Gemini 3.5 Flash", tool: true, provider: "google-genai" },
53
+ { id: "gemini-3.1-flash-lite", name: "Gemini 3.1 Flash-Lite", tool: true, provider: "google-genai" },
54
+ { id: "gemini-3.1-pro", name: "Gemini 3.1 Pro", tool: true, provider: "google-genai" },
55
55
  // Ollama models
56
- { id: "granite3.1-moe:latest", name: "Granite 3.1 Moe", tool: true, provider: "ollama" },
57
- { id: "granite3.1-dense:latest", name: "Granite 3.1 Dense", tool: true, provider: "ollama" },
56
+ { id: "granite4.1:3b", name: "Granite 4.1 3B", tool: true, provider: "ollama" },
58
57
  { id: "llama3:latest", name: "Llama 3", tool: false, provider: "ollama" },
59
58
  { id: "llama3.2:latest", name: "Llama 3.2", tool: true, provider: "ollama" },
59
+ { id: "gemma4:e4b", name: "Gemma 4 4B", tool: true, provider: "ollama" },
60
+ { id: "gemma4:e4b-mlx", name: "Gemma 4 4B MLX", tool: true, provider: "ollama" },
60
61
  { id: "phi4:latest", name: "Phi 4", tool: false, provider: "ollama" },
61
62
  { id: "phi3.5:latest", name: "Phi 3.5", tool: false, provider: "ollama" },
62
63
  { id: "qwen3.5:4b", name: "Qwen 3.5 4B", tool: true, provider: "ollama" },
64
+ { id: "qwen3.5:4b-mlx", name: "Qwen 3.5 4B MLX", tool: true, provider: "ollama" },
63
65
  { id: "qwen3.5:latest", name: "Qwen 3.5", tool: true, provider: "ollama" }
64
66
  ];
65
67
  }
@@ -106,13 +108,13 @@ var init_ai_service = __esm({
106
108
  model;
107
109
  llm;
108
110
  llmWithTools;
109
- messages = [];
111
+ memory = {};
110
112
  reset(model) {
111
113
  if (this.model && this.model.id === model.id && this.llm && (!model.tool || this.llmWithTools)) {
112
114
  return;
113
115
  }
114
116
  log.info("AI model to use:", model.id);
115
- this.messages = [];
117
+ this.memory = {};
116
118
  const { token } = aiPreferencesService.loadOptions();
117
119
  this.model = model;
118
120
  try {
@@ -187,40 +189,51 @@ var init_ai_service = __esm({
187
189
  return String(error);
188
190
  }
189
191
  }
190
- newChat(message, system) {
192
+ newChat(dialogId, message, system) {
191
193
  if (system) {
192
- this.messages = [new import_messages.SystemMessage(system)];
194
+ this.memory[dialogId] = [new import_messages.SystemMessage(system)];
193
195
  } else {
194
- this.messages = [];
196
+ this.memory[dialogId] = [];
195
197
  }
196
- return this.chat(message);
198
+ return this.chat(dialogId, message);
197
199
  }
198
- async chat(message) {
199
- this.messages.push(new import_messages.HumanMessage(message));
200
- const answer = await this.invoke(this.messages);
200
+ async chat(dialogId, message) {
201
+ let messages = this.memory[dialogId];
202
+ if (!messages) {
203
+ messages = [];
204
+ this.memory[dialogId] = messages;
205
+ }
206
+ messages.push(new import_messages.HumanMessage(message));
207
+ const answer = await this.invoke(messages);
201
208
  if (typeof answer !== "string") {
202
- this.messages.push(answer);
209
+ messages.push(answer);
203
210
  }
211
+ log.debug("Current messages:", messages);
204
212
  return answer;
205
213
  }
206
- async invokeTools(toolCalls) {
214
+ async invokeTools(dialogId, toolCalls) {
207
215
  if (!this.llmWithTools) {
208
216
  return "Tool invocation not supported";
209
217
  }
218
+ let messages = this.memory[dialogId];
219
+ if (!messages) {
220
+ messages = [];
221
+ this.memory[dialogId] = messages;
222
+ }
210
223
  for (const call of toolCalls) {
211
224
  log.debug("\u{1F6E0}\uFE0F Call:", call.name, JSON.stringify(call.args));
212
225
  const selectedTool = TOOLS_BY_NAME[call.name];
213
226
  const toolAnswer = await selectedTool?.invoke(call);
214
227
  if (toolAnswer) {
215
228
  log.debug("\u{1F6E0}\uFE0F " + call.name + ":", toolAnswer);
216
- this.messages.push(toolAnswer);
229
+ messages.push(toolAnswer);
217
230
  }
218
231
  }
219
- const finalAnswer = await this.llmWithTools.invoke(this.messages);
232
+ const finalAnswer = await this.llmWithTools.invoke(messages);
220
233
  if (finalAnswer) {
221
- this.messages.push(finalAnswer);
234
+ messages.push(finalAnswer);
222
235
  }
223
- console.debug("Messages>>", this.messages);
236
+ console.debug("Messages>>", messages);
224
237
  return finalAnswer;
225
238
  }
226
239
  generateId() {
@@ -254,9 +267,11 @@ var init_ai_service = __esm({
254
267
  };
255
268
  }
256
269
  extractThink(message) {
257
- const think = message.match(/<think>(.*?)<\/think>/s)?.[1]?.trim();
258
- const content = message.replace(/<think>.*?<\/think>/s, "");
259
- log.debug("extractThink - content:", content, "think:", think);
270
+ const content = message.content;
271
+ let think;
272
+ if (message.additional_kwargs?.reasoning_content) {
273
+ think = message.additional_kwargs?.reasoning_content;
274
+ }
260
275
  return { content, think };
261
276
  }
262
277
  toBotMessage(answer, thinkInfo, toolCallsInfo, toolCallsApprove) {
@@ -264,7 +279,7 @@ var init_ai_service = __esm({
264
279
  return aiService.createBotMessage(`Error: ${answer}`);
265
280
  }
266
281
  if (!answer.tool_calls || answer.tool_calls.length === 0) {
267
- const { content: content2, think } = aiService.extractThink(answer.content);
282
+ const { content: content2, think } = aiService.extractThink(answer);
268
283
  const extraContent2 = think ? { beforeMainContent: thinkInfo(think) } : void 0;
269
284
  return aiService.createBotMessage(content2, extraContent2);
270
285
  }
@@ -1940,6 +1955,34 @@ var init_react_split_es = __esm({
1940
1955
  }
1941
1956
  });
1942
1957
 
1958
+ // src/ai-plugin/jmx-ai/model.ts
1959
+ var ChatbotDialog;
1960
+ var init_model = __esm({
1961
+ "src/ai-plugin/jmx-ai/model.ts"() {
1962
+ "use strict";
1963
+ ChatbotDialog = class {
1964
+ constructor(messages, summary) {
1965
+ this.messages = messages;
1966
+ this.summary = summary;
1967
+ this.id = messages[0]?.id ?? "";
1968
+ }
1969
+ messages;
1970
+ summary;
1971
+ id;
1972
+ setMessages(messages) {
1973
+ if (messages[0]?.id !== this.id) {
1974
+ throw new Error("Not the same dialog");
1975
+ }
1976
+ this.messages = [...messages];
1977
+ }
1978
+ createConversation() {
1979
+ const text = this.summary ?? (this.messages[0]?.content ?? "").substring(0, 20);
1980
+ return { id: this.id, text };
1981
+ }
1982
+ };
1983
+ }
1984
+ });
1985
+
1943
1986
  // src/ai-plugin/jmx-ai/context.ts
1944
1987
  function useMBeanTree() {
1945
1988
  const [tree, setTree] = (0, import_react7.useState)(import_react6.MBeanTree.createEmpty(pluginName));
@@ -2000,13 +2043,38 @@ function pluginPathWithNodeId(node, searchParams = new URLSearchParams(window.lo
2000
2043
  }
2001
2044
  function useChatbot() {
2002
2045
  const [messages, setMessages] = (0, import_react7.useState)([]);
2003
- const [conversations, setConversations] = (0, import_react7.useState)(initialConversations);
2046
+ const [dialogs, setDialogs] = (0, import_react7.useState)([]);
2047
+ const [conversations, setConversations] = (0, import_react7.useState)([]);
2004
2048
  const [announcement, setAnnouncement] = (0, import_react7.useState)("");
2005
2049
  const [isChatbotOpen, setIsChatbotOpen] = (0, import_react7.useState)(false);
2006
2050
  const [isSendButtonDisabled, setIsSendButtonDisabled] = (0, import_react7.useState)(false);
2051
+ const updateConversations = (messages2, summary) => {
2052
+ const dialogId = messages2[0]?.id;
2053
+ if (!dialogId) {
2054
+ return;
2055
+ }
2056
+ setMessages(messages2);
2057
+ let dialog = dialogs.find((d) => d.id === dialogId);
2058
+ if (dialog) {
2059
+ dialog.setMessages(messages2);
2060
+ } else {
2061
+ dialog = new ChatbotDialog(messages2, summary);
2062
+ dialogs.push(dialog);
2063
+ }
2064
+ setDialogs([...dialogs]);
2065
+ log.debug("Updated dialogs:", dialogs);
2066
+ if (!conversations.some((c) => c.id === dialogId)) {
2067
+ const conversation = dialog.createConversation();
2068
+ conversations.push(conversation);
2069
+ setConversations([...conversations]);
2070
+ log.debug("Updated conversations:", conversations);
2071
+ }
2072
+ };
2007
2073
  return {
2008
2074
  messages,
2009
2075
  setMessages,
2076
+ dialogs,
2077
+ setDialogs,
2010
2078
  conversations,
2011
2079
  setConversations,
2012
2080
  announcement,
@@ -2014,10 +2082,11 @@ function useChatbot() {
2014
2082
  isChatbotOpen,
2015
2083
  setIsChatbotOpen,
2016
2084
  isSendButtonDisabled,
2017
- setIsSendButtonDisabled
2085
+ setIsSendButtonDisabled,
2086
+ updateConversations
2018
2087
  };
2019
2088
  }
2020
- var import_react6, import_react7, import_react_router_dom, MBeanTreeContext, initialConversations, ChatbotContext;
2089
+ var import_react6, import_react7, import_react_router_dom, MBeanTreeContext, ChatbotContext;
2021
2090
  var init_context = __esm({
2022
2091
  "src/ai-plugin/jmx-ai/context.ts"() {
2023
2092
  "use strict";
@@ -2025,18 +2094,22 @@ var init_context = __esm({
2025
2094
  import_react7 = require("react");
2026
2095
  import_react_router_dom = require("react-router-dom");
2027
2096
  init_globals();
2097
+ init_model();
2028
2098
  MBeanTreeContext = (0, import_react7.createContext)({
2029
2099
  tree: import_react6.MBeanTree.createEmpty(pluginName),
2100
+ loaded: false,
2030
2101
  selectedNode: null,
2031
2102
  setSelectedNode: () => {
2032
2103
  }
2033
2104
  });
2034
- initialConversations = {};
2035
2105
  ChatbotContext = (0, import_react7.createContext)({
2036
2106
  messages: [],
2037
2107
  setMessages: () => {
2038
2108
  },
2039
- conversations: initialConversations,
2109
+ dialogs: [],
2110
+ setDialogs: () => {
2111
+ },
2112
+ conversations: [],
2040
2113
  setConversations: () => {
2041
2114
  },
2042
2115
  announcement: "",
@@ -2047,6 +2120,8 @@ var init_context = __esm({
2047
2120
  },
2048
2121
  isSendButtonDisabled: false,
2049
2122
  setIsSendButtonDisabled: () => {
2123
+ },
2124
+ updateConversations: () => {
2050
2125
  }
2051
2126
  });
2052
2127
  }
@@ -2059,10 +2134,12 @@ var init_Jmx = __esm({
2059
2134
  });
2060
2135
 
2061
2136
  // src/ai-plugin/jmx-ai/DiagnosisChatbot.tsx
2062
- var import_Chatbot, import_ChatbotContent, import_ChatbotConversationHistoryNav, import_ChatbotFooter, import_ChatbotHeader, import_Message, import_MessageBar, import_MessageBox, import_react_core2, import_wrench_icon, import_react8, import_jsx_runtime2, DiagnosisChatbot, DiagnosisChatbotHeader, DiagnosisChatbotContent, DiagnosisChatbotFooter, ThinkInfo, ToolCallsInfo, ToolCallsApprove;
2137
+ var import_ui, import_chatbot, import_Chatbot, import_ChatbotContent, import_ChatbotConversationHistoryNav, import_ChatbotFooter, import_ChatbotHeader, import_Message, import_MessageBar, import_MessageBox, import_react_core2, import_wrench_icon, import_react8, import_jsx_runtime2, DiagnosisChatbot, DiagnosisChatbotHeader, DiagnosisChatbotContent, DiagnosisChatbotFooter, ThinkInfo, ToolCallsInfo, ToolCallsApprove;
2063
2138
  var init_DiagnosisChatbot = __esm({
2064
2139
  "src/ai-plugin/jmx-ai/DiagnosisChatbot.tsx"() {
2065
2140
  "use strict";
2141
+ import_ui = require("@hawtio/react/ui");
2142
+ import_chatbot = require("@patternfly/chatbot");
2066
2143
  import_Chatbot = __toESM(require("@patternfly/chatbot/dist/dynamic/Chatbot"));
2067
2144
  import_ChatbotContent = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotContent"));
2068
2145
  import_ChatbotConversationHistoryNav = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav"));
@@ -2079,25 +2156,25 @@ var init_DiagnosisChatbot = __esm({
2079
2156
  init_globals();
2080
2157
  import_jsx_runtime2 = require("react/jsx-runtime");
2081
2158
  DiagnosisChatbot = () => {
2082
- const { setMessages, conversations, setConversations } = (0, import_react8.useContext)(ChatbotContext);
2159
+ const { setMessages, dialogs, conversations } = (0, import_react8.useContext)(ChatbotContext);
2083
2160
  const [isDrawerOpen, setIsDrawerOpen] = (0, import_react8.useState)(false);
2084
- const findMatchingItems = (targetValue) => {
2085
- let filteredConversations = Object.entries(initialConversations).reduce(
2086
- (acc, [key, items]) => {
2087
- const filteredItems = items.filter(
2088
- (item) => item.text.toLowerCase().includes(targetValue.toLowerCase())
2089
- );
2090
- if (filteredItems.length > 0) {
2091
- acc[key] = filteredItems;
2092
- }
2093
- return acc;
2094
- },
2095
- {}
2096
- );
2097
- if (Object.keys(filteredConversations).length === 0) {
2098
- filteredConversations = [{ id: "13", noIcon: true, text: "No results found" }];
2161
+ const [filteredConversations, setFilteredConversations] = (0, import_react8.useState)(conversations);
2162
+ const onSelectItemInHistory = (selected) => {
2163
+ log.debug("Selected conversation with ID:", selected);
2164
+ const dialog = dialogs.find((c) => c.id === selected);
2165
+ if (dialog) {
2166
+ setMessages(dialog.messages);
2167
+ setIsDrawerOpen(!isDrawerOpen);
2099
2168
  }
2100
- return filteredConversations;
2169
+ };
2170
+ const handleSearchTextChange = (value) => {
2171
+ if (value.trim() === "") {
2172
+ setFilteredConversations(conversations);
2173
+ return;
2174
+ }
2175
+ const filtered = conversations.filter((c) => c.text.toLowerCase().includes(value.toLowerCase()));
2176
+ log.debug("Filtered conversations:", filtered);
2177
+ setFilteredConversations(filtered);
2101
2178
  };
2102
2179
  const displayMode = import_Chatbot.ChatbotDisplayMode.drawer;
2103
2180
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Chatbot.default, { isCompact: true, displayMode, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -2108,25 +2185,18 @@ var init_DiagnosisChatbot = __esm({
2108
2185
  displayMode,
2109
2186
  onDrawerToggle: () => {
2110
2187
  setIsDrawerOpen(!isDrawerOpen);
2111
- setConversations(initialConversations);
2188
+ setFilteredConversations(conversations);
2112
2189
  },
2113
2190
  isDrawerOpen,
2114
2191
  setIsDrawerOpen,
2115
- activeItemId: "1",
2116
- onSelectActiveItem: (_e, selectedItem) => log.debug(`Selected history item with id ${selectedItem}`),
2117
- conversations,
2192
+ onSelectActiveItem: (_e, selectedItem) => onSelectItemInHistory(String(selectedItem)),
2193
+ conversations: [...filteredConversations].reverse(),
2118
2194
  onNewChat: () => {
2119
2195
  setIsDrawerOpen(!isDrawerOpen);
2196
+ setFilteredConversations(conversations);
2120
2197
  setMessages([]);
2121
- setConversations(initialConversations);
2122
- },
2123
- handleTextInputChange: (value) => {
2124
- if (value === "") {
2125
- setConversations(initialConversations);
2126
- }
2127
- const newConversations = findMatchingItems(value);
2128
- setConversations(newConversations);
2129
2198
  },
2199
+ handleTextInputChange: handleSearchTextChange,
2130
2200
  drawerContent: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2131
2201
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DiagnosisChatbotHeader, { isDrawerOpen, setIsDrawerOpen }),
2132
2202
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DiagnosisChatbotContent, {}),
@@ -2163,8 +2233,8 @@ var init_DiagnosisChatbot = __esm({
2163
2233
  ] }, message.id)) }) });
2164
2234
  };
2165
2235
  DiagnosisChatbotFooter = () => {
2166
- const username = "user";
2167
- const { messages, setMessages, setAnnouncement, isSendButtonDisabled, setIsSendButtonDisabled } = (0, import_react8.useContext)(ChatbotContext);
2236
+ const { username } = (0, import_react8.useContext)(import_ui.PageContext);
2237
+ const { messages, setAnnouncement, isSendButtonDisabled, setIsSendButtonDisabled, updateConversations } = (0, import_react8.useContext)(ChatbotContext);
2168
2238
  const messagesRef = (0, import_react8.useRef)(messages);
2169
2239
  (0, import_react8.useEffect)(() => {
2170
2240
  messagesRef.current = messages;
@@ -2179,17 +2249,18 @@ var init_DiagnosisChatbot = __esm({
2179
2249
  newMessages.push(...messagesRef.current);
2180
2250
  newMessages.push(aiService.createUserMessage(username, message));
2181
2251
  newMessages.push(aiService.createLoadingBotMessage());
2182
- setMessages(newMessages);
2252
+ updateConversations(newMessages);
2183
2253
  setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`);
2184
2254
  log.debug("handleSend - new messages:", newMessages);
2185
- const answer = await (newMessages.length === 2 ? aiService.newChat(message) : aiService.chat(message));
2255
+ const dialogId = newMessages[0].id;
2256
+ const answer = await (newMessages.length === 2 ? aiService.newChat(dialogId, message) : aiService.chat(dialogId, message));
2186
2257
  const loadedMessages = [];
2187
2258
  loadedMessages.push(...newMessages);
2188
2259
  log.debug("handleSend - loaded messages:", loadedMessages);
2189
2260
  loadedMessages.pop();
2190
2261
  const botMessage = aiService.toBotMessage(answer, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
2191
2262
  loadedMessages.push(botMessage);
2192
- setMessages(loadedMessages);
2263
+ updateConversations(loadedMessages);
2193
2264
  setAnnouncement(`Message from Bot: ${answer}`);
2194
2265
  setIsSendButtonDisabled(false);
2195
2266
  };
@@ -2206,7 +2277,7 @@ var init_DiagnosisChatbot = __esm({
2206
2277
  ] });
2207
2278
  };
2208
2279
  ThinkInfo = (think) => {
2209
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Alert, { variant: "info", title: "Think", isExpandable: true, children: think });
2280
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Alert, { variant: "info", title: "Thinking", isExpandable: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_chatbot.MarkdownContent, { content: think }) });
2210
2281
  };
2211
2282
  ToolCallsInfo = (call, index) => {
2212
2283
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Alert, { variant: "info", customIcon: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_wrench_icon.default, {}), title: call.name, isExpandable: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
@@ -2216,8 +2287,8 @@ var init_DiagnosisChatbot = __esm({
2216
2287
  ] }) }, index);
2217
2288
  };
2218
2289
  ToolCallsApprove = (toolCalls) => {
2219
- const username = "user";
2220
- const { messages, setMessages, setAnnouncement, setIsSendButtonDisabled } = (0, import_react8.useContext)(ChatbotContext);
2290
+ const { username } = (0, import_react8.useContext)(import_ui.PageContext);
2291
+ const { messages, setAnnouncement, setIsSendButtonDisabled, updateConversations } = (0, import_react8.useContext)(ChatbotContext);
2221
2292
  const messagesRef = (0, import_react8.useRef)(messages);
2222
2293
  const approve = async (toolCalls2) => {
2223
2294
  log.debug("Approved", messagesRef.current);
@@ -2226,10 +2297,11 @@ var init_DiagnosisChatbot = __esm({
2226
2297
  newMessages.push(...messagesRef.current);
2227
2298
  newMessages.push(aiService.createUserMessage(username, "Approved"));
2228
2299
  newMessages.push(aiService.createLoadingBotMessage());
2229
- setMessages(newMessages);
2300
+ updateConversations(newMessages);
2230
2301
  setAnnouncement(`User approved tool usage. Message from Bot is loading.`);
2231
2302
  log.debug("approve - newMessages:", newMessages);
2232
- const answer = await aiService.invokeTools(toolCalls2);
2303
+ const dialogId = newMessages[0].id;
2304
+ const answer = await aiService.invokeTools(dialogId, toolCalls2);
2233
2305
  log.debug("Answer:", answer);
2234
2306
  const loadedMessages = [];
2235
2307
  loadedMessages.push(...newMessages);
@@ -2237,7 +2309,7 @@ var init_DiagnosisChatbot = __esm({
2237
2309
  loadedMessages.pop();
2238
2310
  const botMessage = aiService.toBotMessage(answer, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
2239
2311
  loadedMessages.push(botMessage);
2240
- setMessages(loadedMessages);
2312
+ updateConversations(loadedMessages);
2241
2313
  setAnnouncement(`Message from Bot: ${answer}`);
2242
2314
  setIsSendButtonDisabled(false);
2243
2315
  };
@@ -2247,7 +2319,7 @@ var init_DiagnosisChatbot = __esm({
2247
2319
  const newMessages = [];
2248
2320
  newMessages.push(...messages);
2249
2321
  newMessages.push(aiService.createUserMessage(username, "Rejected"));
2250
- setMessages(newMessages);
2322
+ updateConversations(newMessages);
2251
2323
  setIsSendButtonDisabled(false);
2252
2324
  };
2253
2325
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_core2.Flex, { columnGap: { default: "columnGapSm" }, children: [
@@ -2264,111 +2336,6 @@ var init_JmxContent = __esm({
2264
2336
  }
2265
2337
  });
2266
2338
 
2267
- // src/ai-plugin/jmx-ai/util.ts
2268
- function isObject(value) {
2269
- const type = typeof value;
2270
- return value != null && (type === "object" || type === "function");
2271
- }
2272
- function isNumber(value) {
2273
- return typeof value === "number" && !Number.isNaN(value);
2274
- }
2275
- function stringSorter(a, b, sortDesc) {
2276
- let res = a.localeCompare(b);
2277
- if (sortDesc) {
2278
- res *= -1;
2279
- }
2280
- return res;
2281
- }
2282
- function objectSorter(aValue, bValue, sortDesc) {
2283
- if (isNumber(aValue)) {
2284
- if (!sortDesc) {
2285
- return aValue - bValue;
2286
- }
2287
- return bValue - aValue;
2288
- } else {
2289
- return stringSorter(aValue, bValue, sortDesc);
2290
- }
2291
- }
2292
- function escapeMBean(mbean) {
2293
- return encodeURI(applyJolokiaEscapeRules(mbean));
2294
- }
2295
- function applyJolokiaEscapeRules(mbean) {
2296
- return mbean.replace(/!/g, "!!").replace(/\//g, "!/").replace(/"/g, '!"');
2297
- }
2298
- var init_util = __esm({
2299
- "src/ai-plugin/jmx-ai/util.ts"() {
2300
- "use strict";
2301
- }
2302
- });
2303
-
2304
- // src/ai-plugin/jmx-ai/attributes/attribute-service.ts
2305
- var import_react9, AttributeService, attributeService;
2306
- var init_attribute_service = __esm({
2307
- "src/ai-plugin/jmx-ai/attributes/attribute-service.ts"() {
2308
- "use strict";
2309
- import_react9 = require("@hawtio/react");
2310
- init_globals();
2311
- init_util();
2312
- AttributeService = class {
2313
- handles = [];
2314
- requestOptions() {
2315
- return {};
2316
- }
2317
- setupConfig(request) {
2318
- return request;
2319
- }
2320
- async read(mbean) {
2321
- return await import_react9.jolokiaService.readAttributes(mbean, this.requestOptions());
2322
- }
2323
- async readWithCallback(mbean, callback) {
2324
- const attrs = await import_react9.jolokiaService.readAttributes(mbean, this.requestOptions());
2325
- callback(attrs);
2326
- }
2327
- async register(request, callback) {
2328
- const handle = await import_react9.jolokiaService.register(this.setupConfig(request), callback);
2329
- log.debug("Register handle:", handle);
2330
- this.handles.push(handle);
2331
- }
2332
- unregisterAll() {
2333
- log.debug("Unregister all handles:", this.handles);
2334
- this.handles.forEach((handle) => import_react9.jolokiaService.unregister(handle));
2335
- this.handles = [];
2336
- }
2337
- async buildUrl(mbean, attribute) {
2338
- const jolokiaUrl = await import_react9.jolokiaService.getFullJolokiaUrl();
2339
- return `${jolokiaUrl}/read/${escapeMBean(mbean)}/${attribute}`;
2340
- }
2341
- async canInvoke(mbean, attribute, type) {
2342
- return true;
2343
- }
2344
- async update(mbeanName, attribute, value) {
2345
- await import_react9.jolokiaService.writeAttribute(mbeanName, attribute, value, this.requestOptions());
2346
- import_react9.eventService.notify({ type: "success", message: `Updated attribute: ${attribute}` });
2347
- }
2348
- async bulkRequest(requests) {
2349
- return import_react9.jolokiaService.bulkRequest(requests.map(this.setupConfig));
2350
- }
2351
- };
2352
- attributeService = new AttributeService();
2353
- }
2354
- });
2355
-
2356
- // src/ai-plugin/jmx-ai/attributes/AttributeModal.tsx
2357
- var import_react10, import_react_core3, import_react_icons, import_react11, import_jsx_runtime3;
2358
- var init_AttributeModal = __esm({
2359
- "src/ai-plugin/jmx-ai/attributes/AttributeModal.tsx"() {
2360
- "use strict";
2361
- import_react10 = require("@hawtio/react");
2362
- import_react_core3 = require("@patternfly/react-core");
2363
- import_react_icons = require("@patternfly/react-icons");
2364
- import_react11 = require("react");
2365
- init_ai_service();
2366
- init_globals();
2367
- init_attribute_service();
2368
- import_jsx_runtime3 = require("react/jsx-runtime");
2369
- }
2370
- });
2371
-
2372
2339
  // node_modules/jolokia.js/dist/jolokia.mjs
2373
2340
  function prepareRequest(request, agentOptions, params) {
2374
2341
  const opts = Object.assign({}, agentOptions, { dataType: "json" }, params);
@@ -3185,34 +3152,124 @@ What potential issues or anomalies do you see?`;
3185
3152
  }
3186
3153
  });
3187
3154
 
3155
+ // src/ai-plugin/jmx-ai/util.ts
3156
+ function isObject(value) {
3157
+ const type = typeof value;
3158
+ return value != null && (type === "object" || type === "function");
3159
+ }
3160
+ function isNumber(value) {
3161
+ return typeof value === "number" && !Number.isNaN(value);
3162
+ }
3163
+ function stringSorter(a, b, sortDesc) {
3164
+ let res = a.localeCompare(b);
3165
+ if (sortDesc) {
3166
+ res *= -1;
3167
+ }
3168
+ return res;
3169
+ }
3170
+ function objectSorter(aValue, bValue, sortDesc) {
3171
+ if (isNumber(aValue)) {
3172
+ if (!sortDesc) {
3173
+ return aValue - bValue;
3174
+ }
3175
+ return bValue - aValue;
3176
+ } else {
3177
+ return stringSorter(aValue, bValue, sortDesc);
3178
+ }
3179
+ }
3180
+ function escapeMBean(mbean) {
3181
+ return encodeURI(applyJolokiaEscapeRules(mbean));
3182
+ }
3183
+ function applyJolokiaEscapeRules(mbean) {
3184
+ return mbean.replace(/!/g, "!!").replace(/\//g, "!/").replace(/"/g, '!"');
3185
+ }
3186
+ var init_util = __esm({
3187
+ "src/ai-plugin/jmx-ai/util.ts"() {
3188
+ "use strict";
3189
+ }
3190
+ });
3191
+
3192
+ // src/ai-plugin/jmx-ai/attributes/attribute-service.ts
3193
+ var import_react9, AttributeService, attributeService;
3194
+ var init_attribute_service = __esm({
3195
+ "src/ai-plugin/jmx-ai/attributes/attribute-service.ts"() {
3196
+ "use strict";
3197
+ import_react9 = require("@hawtio/react");
3198
+ init_globals();
3199
+ init_util();
3200
+ AttributeService = class {
3201
+ handles = [];
3202
+ requestOptions() {
3203
+ return {};
3204
+ }
3205
+ setupConfig(request) {
3206
+ return request;
3207
+ }
3208
+ async read(mbean) {
3209
+ return await import_react9.jolokiaService.readAttributes(mbean, this.requestOptions());
3210
+ }
3211
+ async readWithCallback(mbean, callback) {
3212
+ const attrs = await import_react9.jolokiaService.readAttributes(mbean, this.requestOptions());
3213
+ callback(attrs);
3214
+ }
3215
+ async register(request, callback) {
3216
+ const handle = await import_react9.jolokiaService.register(this.setupConfig(request), callback);
3217
+ log.debug("Register handle:", handle);
3218
+ this.handles.push(handle);
3219
+ }
3220
+ unregisterAll() {
3221
+ log.debug("Unregister all handles:", this.handles);
3222
+ this.handles.forEach((handle) => import_react9.jolokiaService.unregister(handle));
3223
+ this.handles = [];
3224
+ }
3225
+ async buildUrl(mbean, attribute) {
3226
+ const jolokiaUrl = await import_react9.jolokiaService.getFullJolokiaUrl();
3227
+ return `${jolokiaUrl}/read/${escapeMBean(mbean)}/${attribute}`;
3228
+ }
3229
+ async canInvoke(mbean, attribute, type) {
3230
+ return true;
3231
+ }
3232
+ async update(mbeanName, attribute, value) {
3233
+ await import_react9.jolokiaService.writeAttribute(mbeanName, attribute, value, this.requestOptions());
3234
+ import_react9.eventService.notify({ type: "success", message: `Updated attribute: ${attribute}` });
3235
+ }
3236
+ async bulkRequest(requests) {
3237
+ return import_react9.jolokiaService.bulkRequest(requests.map(this.setupConfig));
3238
+ }
3239
+ };
3240
+ attributeService = new AttributeService();
3241
+ }
3242
+ });
3243
+
3188
3244
  // src/ai-plugin/jmx-ai/attributes/Attributes.tsx
3189
- var import_react12, import_react_core4, import_react_icons2, import_react_table, import_react13, import_jsx_runtime4, Attributes, AiJmxToolbar;
3245
+ var import_react10, import_ui2, import_react_core3, import_react_icons, import_react_table, import_react11, import_jsx_runtime3, Attributes, AiJmxToolbar;
3190
3246
  var init_Attributes = __esm({
3191
3247
  "src/ai-plugin/jmx-ai/attributes/Attributes.tsx"() {
3192
3248
  "use strict";
3193
- import_react12 = require("@hawtio/react");
3194
- import_react_core4 = require("@patternfly/react-core");
3195
- import_react_icons2 = require("@patternfly/react-icons");
3249
+ import_react10 = require("@hawtio/react");
3250
+ import_ui2 = require("@hawtio/react/ui");
3251
+ import_react_core3 = require("@patternfly/react-core");
3252
+ import_react_icons = require("@patternfly/react-icons");
3196
3253
  import_react_table = require("@patternfly/react-table");
3197
3254
  init_jolokia();
3198
- import_react13 = require("react");
3255
+ import_react11 = require("react");
3199
3256
  init_ai_service();
3200
3257
  init_context();
3258
+ init_DiagnosisChatbot();
3201
3259
  init_globals();
3202
3260
  init_jmx_ai_service();
3203
3261
  init_util();
3204
3262
  init_attribute_service();
3205
- init_DiagnosisChatbot();
3206
- import_jsx_runtime4 = require("react/jsx-runtime");
3263
+ import_jsx_runtime3 = require("react/jsx-runtime");
3207
3264
  Attributes = () => {
3208
- const { selectedNode } = (0, import_react13.useContext)(MBeanTreeContext);
3209
- const [attributes, setAttributes] = (0, import_react13.useState)({});
3210
- const [isReading, setIsReading] = (0, import_react13.useState)(true);
3211
- const [isModalOpen, setIsModalOpen] = (0, import_react13.useState)(false);
3212
- const [sortDirection, setSortDirection] = (0, import_react13.useState)("asc");
3213
- const [selected, setSelected] = (0, import_react13.useState)({ name: "", value: "" });
3214
- const [reload, setReload] = (0, import_react13.useState)(false);
3215
- (0, import_react13.useEffect)(() => {
3265
+ const { selectedNode } = (0, import_react11.useContext)(MBeanTreeContext);
3266
+ const [attributes, setAttributes] = (0, import_react11.useState)({});
3267
+ const [isReading, setIsReading] = (0, import_react11.useState)(true);
3268
+ const [isModalOpen, setIsModalOpen] = (0, import_react11.useState)(false);
3269
+ const [sortDirection, setSortDirection] = (0, import_react11.useState)("asc");
3270
+ const [selected, setSelected] = (0, import_react11.useState)({ name: "", value: "" });
3271
+ const [reload, setReload] = (0, import_react11.useState)(false);
3272
+ (0, import_react11.useEffect)(() => {
3216
3273
  if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {
3217
3274
  return;
3218
3275
  }
@@ -3232,7 +3289,7 @@ var init_Attributes = __esm({
3232
3289
  );
3233
3290
  return () => attributeService.unregisterAll();
3234
3291
  }, [selectedNode]);
3235
- (0, import_react13.useEffect)(() => {
3292
+ (0, import_react11.useEffect)(() => {
3236
3293
  if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName || !reload) {
3237
3294
  return;
3238
3295
  }
@@ -3248,14 +3305,14 @@ var init_Attributes = __esm({
3248
3305
  return null;
3249
3306
  }
3250
3307
  if (isReading) {
3251
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react12.HawtioLoadingCard, {});
3308
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react10.HawtioLoadingCard, {});
3252
3309
  }
3253
3310
  const rows = Object.entries(attributes).map(([name, value]) => ({
3254
3311
  name,
3255
3312
  value: isObject(value) ? JSON.stringify(value) : String(value)
3256
3313
  }));
3257
3314
  if (rows.length === 0) {
3258
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react12.HawtioEmptyCard, { message: "This MBean has no attributes." });
3315
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react10.HawtioEmptyCard, { message: "This MBean has no attributes." });
3259
3316
  }
3260
3317
  const selectAttribute = (attribute) => {
3261
3318
  setSelected(attribute);
@@ -3275,8 +3332,8 @@ var init_Attributes = __esm({
3275
3332
  },
3276
3333
  columnIndex: 0
3277
3334
  });
3278
- const panelContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3279
- import_react12.AttributeModal,
3335
+ const panelContent = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3336
+ import_react10.AttributeModal,
3280
3337
  {
3281
3338
  isOpen: isModalOpen,
3282
3339
  onClose: () => setIsModalOpen(false),
@@ -3284,34 +3341,34 @@ var init_Attributes = __esm({
3284
3341
  input: selected
3285
3342
  }
3286
3343
  );
3287
- const attributesTable = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { id: "attribute-table-with-panel", children: [
3288
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(AiJmxToolbar, { attributes }),
3289
- /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_table.Table, { "aria-label": "Attributes", variant: "compact", children: [
3290
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_table.Tr, { children: [
3291
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_table.Th, { sort: getSortParams(), children: "Attribute" }),
3292
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_table.Th, { children: "Value" })
3344
+ const attributesTable = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { id: "attribute-table-with-panel", children: [
3345
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiJmxToolbar, { attributes }),
3346
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_table.Table, { "aria-label": "Attributes", variant: "compact", children: [
3347
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_table.Tr, { children: [
3348
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Th, { sort: getSortParams(), children: "Attribute" }),
3349
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Th, { children: "Value" })
3293
3350
  ] }) }),
3294
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_table.Tbody, { children: rows.sort((a, b) => objectSorter(a.name, b.name, sortDirection === "desc")).map((att, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
3351
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Tbody, { children: rows.sort((a, b) => objectSorter(a.name, b.name, sortDirection === "desc")).map((att, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
3295
3352
  import_react_table.Tr,
3296
3353
  {
3297
3354
  isClickable: true,
3298
3355
  isRowSelected: selected.name === att.name,
3299
3356
  onRowClick: () => selectAttribute(att),
3300
3357
  children: [
3301
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_table.Td, { children: att.name }),
3302
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_table.Td, { children: att.value })
3358
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Td, { children: att.name }),
3359
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Td, { children: att.value })
3303
3360
  ]
3304
3361
  },
3305
3362
  att.name + "-" + index
3306
3363
  )) })
3307
3364
  ] })
3308
3365
  ] });
3309
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Drawer, { isExpanded: isModalOpen, className: "pf-m-inline-on-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.DrawerContentBody, { hasPadding: true, children: attributesTable }) }) }) });
3366
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.Drawer, { isExpanded: isModalOpen, className: "pf-m-inline-on-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.DrawerContentBody, { hasPadding: true, children: attributesTable }) }) }) });
3310
3367
  };
3311
3368
  AiJmxToolbar = ({ attributes }) => {
3312
- const { selectedNode } = (0, import_react13.useContext)(MBeanTreeContext);
3313
- const username = "user";
3314
- const { setMessages, setAnnouncement, setIsChatbotOpen } = (0, import_react13.useContext)(ChatbotContext);
3369
+ const { selectedNode } = (0, import_react11.useContext)(MBeanTreeContext);
3370
+ const { username } = (0, import_react11.useContext)(import_ui2.PageContext);
3371
+ const { setAnnouncement, setIsChatbotOpen, updateConversations } = (0, import_react11.useContext)(ChatbotContext);
3315
3372
  if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {
3316
3373
  return null;
3317
3374
  }
@@ -3325,20 +3382,21 @@ var init_Attributes = __esm({
3325
3382
  const newMessages = [];
3326
3383
  newMessages.push(aiService.createUserMessage(username, diagnoseMessage));
3327
3384
  newMessages.push(aiService.createLoadingBotMessage());
3328
- setMessages(newMessages);
3385
+ updateConversations(newMessages, `Diagnose ${objectName}`);
3329
3386
  setAnnouncement("Diagnosis in progress...");
3330
3387
  log.debug("diagnose - new messages:", newMessages);
3331
- const answer = await aiService.newChat(diagnoseMessage, systemMessage);
3388
+ const dialogId = newMessages[0].id;
3389
+ const answer = await aiService.newChat(dialogId, diagnoseMessage, systemMessage);
3332
3390
  const loadedMessages = [];
3333
3391
  loadedMessages.push(...newMessages);
3334
3392
  log.debug("diagnose - loaded messages:", loadedMessages);
3335
3393
  loadedMessages.pop();
3336
3394
  const botMessage = aiService.toBotMessage(answer, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
3337
3395
  loadedMessages.push(botMessage);
3338
- setMessages(loadedMessages);
3396
+ updateConversations(loadedMessages);
3339
3397
  setAnnouncement("Diagnosis complete.");
3340
3398
  };
3341
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Toolbar, { id: "ai-jmx-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.ToolbarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.ToolbarItem, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Button, { variant: "primary", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_icons2.MonitoringIcon, {}), onClick: diagnose, children: "Diagnose" }) }) }) });
3399
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.Toolbar, { id: "ai-jmx-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.ToolbarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.ToolbarItem, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.Button, { variant: "primary", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_icons.MonitoringIcon, {}), onClick: diagnose, children: "Diagnose" }) }) }) });
3342
3400
  };
3343
3401
  }
3344
3402
  });
@@ -3347,36 +3405,35 @@ var init_Attributes = __esm({
3347
3405
  var init_attributes = __esm({
3348
3406
  "src/ai-plugin/jmx-ai/attributes/index.ts"() {
3349
3407
  "use strict";
3350
- init_AttributeModal();
3351
3408
  init_Attributes();
3352
3409
  }
3353
3410
  });
3354
3411
 
3355
3412
  // src/ai-plugin/jmx-ai/JmxContent.tsx
3356
- var import_react14, import_react_core5, import_popper_core, import_cubes_icon, import_react15, import_react_router_dom2, import_jsx_runtime5, JmxContent;
3413
+ var import_react12, import_react_core4, import_popper_core, import_cubes_icon, import_react13, import_react_router_dom2, import_jsx_runtime4, JmxContent;
3357
3414
  var init_JmxContent2 = __esm({
3358
3415
  "src/ai-plugin/jmx-ai/JmxContent.tsx"() {
3359
3416
  "use strict";
3360
- import_react14 = require("@hawtio/react");
3361
- import_react_core5 = require("@patternfly/react-core");
3417
+ import_react12 = require("@hawtio/react");
3418
+ import_react_core4 = require("@patternfly/react-core");
3362
3419
  import_popper_core = require("@patternfly/react-core/dist/esm/helpers/Popper/thirdparty/popper-core");
3363
3420
  import_cubes_icon = require("@patternfly/react-icons/dist/esm/icons/cubes-icon");
3364
- import_react15 = __toESM(require("react"));
3421
+ import_react13 = __toESM(require("react"));
3365
3422
  import_react_router_dom2 = require("react-router-dom");
3366
3423
  init_DiagnosisChatbot();
3367
3424
  init_JmxContent();
3368
3425
  init_attributes();
3369
3426
  init_context();
3370
3427
  init_globals();
3371
- import_jsx_runtime5 = require("react/jsx-runtime");
3428
+ import_jsx_runtime4 = require("react/jsx-runtime");
3372
3429
  JmxContent = () => {
3373
- const { selectedNode } = (0, import_react15.useContext)(MBeanTreeContext);
3430
+ const { selectedNode } = (0, import_react13.useContext)(MBeanTreeContext);
3374
3431
  const { pathname, search } = (0, import_react_router_dom2.useLocation)();
3375
3432
  const chatbotContext = useChatbot();
3376
3433
  const { isChatbotOpen, setIsChatbotOpen } = chatbotContext;
3377
- const drawerRef = (0, import_react15.useRef)(void 0);
3434
+ const drawerRef = (0, import_react13.useRef)(void 0);
3378
3435
  if (!selectedNode) {
3379
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.PageSection, { hasBodyWrapper: false, isFilled: true, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.EmptyState, { headingLevel: "h1", icon: import_cubes_icon.CubesIcon, titleText: "Select MBean", variant: "full" }) });
3436
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.PageSection, { hasBodyWrapper: false, isFilled: true, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.EmptyState, { headingLevel: "h1", icon: import_cubes_icon.CubesIcon, titleText: "Select MBean", variant: "full" }) });
3380
3437
  }
3381
3438
  const mBeanApplicable = (node) => Boolean(node.objectName);
3382
3439
  const mBeanCollectionApplicable = (node) => Boolean(node.children?.every((child) => child.objectName));
@@ -3384,42 +3441,42 @@ var init_JmxContent2 = __esm({
3384
3441
  const tableSelector = (node) => {
3385
3442
  const tablePriorityList = [
3386
3443
  { condition: mBeanApplicable, element: Attributes },
3387
- { condition: mBeanCollectionApplicable, element: import_react14.AttributeTable }
3444
+ { condition: mBeanCollectionApplicable, element: import_react12.AttributeTable }
3388
3445
  ];
3389
- return tablePriorityList.find((entry) => entry.condition(node))?.element ?? import_react14.JmxContentMBeans;
3446
+ return tablePriorityList.find((entry) => entry.condition(node))?.element ?? import_react12.JmxContentMBeans;
3390
3447
  };
3391
3448
  const allNavItems = [
3392
3449
  { id: "attributes", title: "Attributes", component: tableSelector(selectedNode), isApplicable: () => true },
3393
- { id: "operations", title: "Operations", component: import_react14.Operations, isApplicable: mBeanApplicable },
3394
- { id: "chart", title: "Chart", component: import_react14.Chart, isApplicable: hasAnyApplicableMBean }
3450
+ { id: "operations", title: "Operations", component: import_react12.Operations, isApplicable: mBeanApplicable },
3451
+ { id: "chart", title: "Chart", component: import_react12.Chart, isApplicable: hasAnyApplicableMBean }
3395
3452
  ];
3396
3453
  const navItems = allNavItems.filter((nav) => nav.isApplicable(selectedNode));
3397
3454
  const searchWithNid = pluginPathWithNodeId(selectedNode, new URLSearchParams(search)).search;
3398
- const mbeanNav = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.Nav, { "aria-label": "MBean Nav", variant: "horizontal-subnav", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.NavList, { children: navItems.map((nav) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.NavItem, { isActive: pathname === `${pluginPath}/${nav.id}`, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_router_dom2.NavLink, { to: { pathname: nav.id, search }, children: nav.title }) }, nav.id)) }) });
3399
- const mbeanRoutes = navItems.map((nav) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_router_dom2.Route, { path: nav.id, element: import_react15.default.createElement(nav.component) }, nav.id));
3400
- const jmxAiToolbar = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.Toolbar, { id: "jmx-ai-toolbar", style: { float: import_popper_core.right }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.ToolbarItem, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.Button, { variant: "secondary", size: "sm", onClick: () => setIsChatbotOpen(!isChatbotOpen), children: "Chat" }) }) });
3401
- const jmxContent = /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core5.PageGroup, { id: "jmx-content", children: [
3402
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_core5.PageSection, { id: "jmx-content-header", hasBodyWrapper: false, children: [
3455
+ const mbeanNav = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Nav, { "aria-label": "MBean Nav", variant: "horizontal-subnav", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.NavList, { children: navItems.map((nav) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.NavItem, { isActive: pathname === `${pluginPath}/${nav.id}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_router_dom2.NavLink, { to: { pathname: nav.id, search }, children: nav.title }) }, nav.id)) }) });
3456
+ const mbeanRoutes = navItems.map((nav) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_router_dom2.Route, { path: nav.id, element: import_react13.default.createElement(nav.component) }, nav.id));
3457
+ const jmxAiToolbar = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Toolbar, { id: "jmx-ai-toolbar", style: { float: import_popper_core.right }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.ToolbarItem, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Button, { variant: "secondary", size: "sm", onClick: () => setIsChatbotOpen(!isChatbotOpen), children: "Chat" }) }) });
3458
+ const jmxContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_core4.PageGroup, { id: "jmx-content", children: [
3459
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_core4.PageSection, { id: "jmx-content-header", hasBodyWrapper: false, children: [
3403
3460
  jmxAiToolbar,
3404
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.Title, { headingLevel: "h1", children: selectedNode.name }),
3405
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.Content, { component: "small", children: selectedNode.objectName })
3461
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Title, { headingLevel: "h1", children: selectedNode.name }),
3462
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Content, { component: "small", children: selectedNode.objectName })
3406
3463
  ] }),
3407
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.PageSection, { type: "tabs", hasBodyWrapper: false, children: mbeanNav }),
3408
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3409
- import_react_core5.PageSection,
3464
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.PageSection, { type: "tabs", hasBodyWrapper: false, children: mbeanNav }),
3465
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3466
+ import_react_core4.PageSection,
3410
3467
  {
3411
3468
  id: "jmx-content-main",
3412
3469
  padding: { default: "noPadding" },
3413
3470
  hasOverflowScroll: true,
3414
3471
  "aria-label": "jmx-content-main",
3415
3472
  hasBodyWrapper: false,
3416
- children: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_react_router_dom2.Routes, { children: [
3473
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_router_dom2.Routes, { children: [
3417
3474
  mbeanRoutes,
3418
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3475
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3419
3476
  import_react_router_dom2.Route,
3420
3477
  {
3421
3478
  path: "/",
3422
- element: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_router_dom2.Navigate, { to: { pathname: navItems[0]?.id ?? "", search: searchWithNid } })
3479
+ element: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_router_dom2.Navigate, { to: { pathname: navItems[0]?.id ?? "", search: searchWithNid } })
3423
3480
  },
3424
3481
  "root"
3425
3482
  )
@@ -3430,8 +3487,8 @@ var init_JmxContent2 = __esm({
3430
3487
  const onDrawerExpand = () => {
3431
3488
  drawerRef.current && drawerRef.current.focus();
3432
3489
  };
3433
- const panelContent = /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.DrawerPanelContent, { isResizable: true, defaultSize: "500px", minSize: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.DrawerPanelBody, { children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(DiagnosisChatbot, {}) }) });
3434
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatbotContext.Provider, { value: chatbotContext, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.Drawer, { isExpanded: isChatbotOpen, isInline: true, onExpand: onDrawerExpand, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.DrawerContentBody, { children: jmxContent }) }) }) });
3490
+ const panelContent = /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.DrawerPanelContent, { isResizable: true, defaultSize: "500px", minSize: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.DrawerPanelBody, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(DiagnosisChatbot, {}) }) });
3491
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatbotContext.Provider, { value: chatbotContext, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Drawer, { isExpanded: isChatbotOpen, isInline: true, onExpand: onDrawerExpand, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.DrawerContentBody, { children: jmxContent }) }) }) });
3435
3492
  };
3436
3493
  }
3437
3494
  });
@@ -3443,23 +3500,23 @@ var init_JmxTreeView = __esm({
3443
3500
  });
3444
3501
 
3445
3502
  // src/ai-plugin/jmx-ai/JmxTreeView.tsx
3446
- var import_react16, import_react_core6, import_react17, import_react_router_dom3, import_jsx_runtime6, JmxTreeView;
3503
+ var import_react14, import_react_core5, import_react15, import_react_router_dom3, import_jsx_runtime5, JmxTreeView;
3447
3504
  var init_JmxTreeView2 = __esm({
3448
3505
  "src/ai-plugin/jmx-ai/JmxTreeView.tsx"() {
3449
3506
  "use strict";
3450
- import_react16 = require("@hawtio/react");
3451
- import_react_core6 = require("@patternfly/react-core");
3452
- import_react17 = require("react");
3507
+ import_react14 = require("@hawtio/react");
3508
+ import_react_core5 = require("@patternfly/react-core");
3509
+ import_react15 = require("react");
3453
3510
  import_react_router_dom3 = require("react-router-dom");
3454
3511
  init_JmxTreeView();
3455
3512
  init_context();
3456
- import_jsx_runtime6 = require("react/jsx-runtime");
3513
+ import_jsx_runtime5 = require("react/jsx-runtime");
3457
3514
  JmxTreeView = () => {
3458
- const { tree, selectedNode, setSelectedNode } = (0, import_react17.useContext)(MBeanTreeContext);
3459
- const [expanded, setExpanded] = (0, import_react17.useState)(0 /* Default */);
3460
- const [filteredTree, setFilteredTree] = (0, import_react17.useState)(tree.getTree());
3515
+ const { tree, selectedNode, setSelectedNode } = (0, import_react15.useContext)(MBeanTreeContext);
3516
+ const [expanded, setExpanded] = (0, import_react15.useState)(0 /* Default */);
3517
+ const [filteredTree, setFilteredTree] = (0, import_react15.useState)(tree.getTree());
3461
3518
  const navigate = (0, import_react_router_dom3.useNavigate)();
3462
- (0, import_react17.useEffect)(() => {
3519
+ (0, import_react15.useEffect)(() => {
3463
3520
  setFilteredTree(tree.getTree());
3464
3521
  }, [tree]);
3465
3522
  const onSearch = (event) => {
@@ -3467,7 +3524,7 @@ var init_JmxTreeView2 = __esm({
3467
3524
  setExpanded(0 /* Default */);
3468
3525
  const input = event.target.value;
3469
3526
  if (!input) setFilteredTree(tree.getTree());
3470
- const treeElements = import_react16.MBeanTree.filter(tree.getTree(), (node) => node.name.toLowerCase().includes(input.toLowerCase()));
3527
+ const treeElements = import_react14.MBeanTree.filter(tree.getTree(), (node) => node.name.toLowerCase().includes(input.toLowerCase()));
3471
3528
  if (treeElements.length === 0) setFilteredTree(tree.getTree());
3472
3529
  else {
3473
3530
  setFilteredTree(treeElements);
@@ -3492,8 +3549,8 @@ var init_JmxTreeView2 = __esm({
3492
3549
  return {};
3493
3550
  }
3494
3551
  };
3495
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
3496
- import_react_core6.TreeView,
3552
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3553
+ import_react_core5.TreeView,
3497
3554
  {
3498
3555
  id: "jmx-tree-view",
3499
3556
  data: filteredTree,
@@ -3502,7 +3559,7 @@ var init_JmxTreeView2 = __esm({
3502
3559
  activeItems: selectedNode ? [selectedNode] : [],
3503
3560
  ...expandedProp(),
3504
3561
  onSelect,
3505
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react16.PluginTreeViewToolbar, { onSearch, onSetExpanded: setAllExpanded })
3562
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react14.PluginTreeViewToolbar, { onSearch, onSetExpanded: setAllExpanded })
3506
3563
  }
3507
3564
  );
3508
3565
  };
@@ -3510,29 +3567,29 @@ var init_JmxTreeView2 = __esm({
3510
3567
  });
3511
3568
 
3512
3569
  // src/ai-plugin/jmx-ai/Jmx.tsx
3513
- var import_react_core7, import_cubes_icon2, import_jsx_runtime7, Jmx;
3570
+ var import_react_core6, import_cubes_icon2, import_jsx_runtime6, Jmx;
3514
3571
  var init_Jmx2 = __esm({
3515
3572
  "src/ai-plugin/jmx-ai/Jmx.tsx"() {
3516
3573
  "use strict";
3517
- import_react_core7 = require("@patternfly/react-core");
3574
+ import_react_core6 = require("@patternfly/react-core");
3518
3575
  import_cubes_icon2 = require("@patternfly/react-icons/dist/esm/icons/cubes-icon");
3519
3576
  init_react_split_es();
3520
3577
  init_context();
3521
3578
  init_Jmx();
3522
3579
  init_JmxContent2();
3523
3580
  init_JmxTreeView2();
3524
- import_jsx_runtime7 = require("react/jsx-runtime");
3581
+ import_jsx_runtime6 = require("react/jsx-runtime");
3525
3582
  Jmx = () => {
3526
3583
  const { tree, loaded, selectedNode, setSelectedNode } = useMBeanTree();
3527
3584
  if (!loaded) {
3528
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.PageSection, { hasBodyWrapper: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.Spinner, { "aria-label": "Loading MBean tree" }) });
3585
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.PageSection, { hasBodyWrapper: false, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.Spinner, { "aria-label": "Loading MBean tree" }) });
3529
3586
  }
3530
3587
  if (tree.isEmpty()) {
3531
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.PageSection, { hasBodyWrapper: false, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.EmptyState, { headingLevel: "h1", icon: import_cubes_icon2.CubesIcon, titleText: "No MBeans found", variant: "full" }) });
3588
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.PageSection, { hasBodyWrapper: false, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.EmptyState, { headingLevel: "h1", icon: import_cubes_icon2.CubesIcon, titleText: "No MBeans found", variant: "full" }) });
3532
3589
  }
3533
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(MBeanTreeContext.Provider, { value: { tree, selectedNode, setSelectedNode }, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(react_split_es_default, { className: "jmx-split", sizes: [30, 70], minSize: 200, gutterSize: 5, children: [
3534
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(JmxTreeView, {}) }),
3535
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(JmxContent, {}) })
3590
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MBeanTreeContext.Provider, { value: { tree, selectedNode, setSelectedNode }, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(react_split_es_default, { className: "jmx-split", sizes: [30, 70], minSize: 200, gutterSize: 5, children: [
3591
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(JmxTreeView, {}) }),
3592
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(JmxContent, {}) })
3536
3593
  ] }) });
3537
3594
  };
3538
3595
  }
@@ -3560,7 +3617,7 @@ __export(index_exports, {
3560
3617
  plugin: () => plugin
3561
3618
  });
3562
3619
  module.exports = __toCommonJS(index_exports);
3563
- var import_react19 = require("@hawtio/react");
3620
+ var import_react17 = require("@hawtio/react");
3564
3621
  var import_main = require("@patternfly/chatbot/dist/css/main.css");
3565
3622
 
3566
3623
  // src/ai-plugin/common/index.ts
@@ -3652,7 +3709,7 @@ var aiCommon = () => {
3652
3709
  };
3653
3710
 
3654
3711
  // src/ai-plugin/jmx-ai/index.ts
3655
- var import_react18 = require("@hawtio/react");
3712
+ var import_react16 = require("@hawtio/react");
3656
3713
  init_globals();
3657
3714
 
3658
3715
  // src/ai-plugin/jmx-ai/help.md
@@ -3662,7 +3719,7 @@ var help_default = "# JMX AI - Hawtio AI Plugin\n\nThis view is provided by the
3662
3719
  var order2 = 41;
3663
3720
  var jmxAi = () => {
3664
3721
  log.info("Loading", pluginName);
3665
- import_react18.hawtio.addDeferredPlugin(pluginName, async () => {
3722
+ import_react16.hawtio.addDeferredPlugin(pluginName, async () => {
3666
3723
  return Promise.resolve().then(() => (init_ui(), ui_exports)).then(({ Jmx: Jmx2 }) => {
3667
3724
  return {
3668
3725
  id: pluginName,
@@ -3670,11 +3727,11 @@ var jmxAi = () => {
3670
3727
  path: pluginPath,
3671
3728
  component: Jmx2,
3672
3729
  knownQueryParams: ["nid"],
3673
- isActive: async () => import_react18.workspace.hasMBeans()
3730
+ isActive: async () => import_react16.workspace.hasMBeans()
3674
3731
  };
3675
3732
  });
3676
3733
  });
3677
- import_react18.helpRegistry.add(pluginName, pluginTitle, help_default, order2);
3734
+ import_react16.helpRegistry.add(pluginName, pluginTitle, help_default, order2);
3678
3735
  };
3679
3736
 
3680
3737
  // src/ai-plugin/index.ts
@@ -3682,7 +3739,7 @@ var plugin = () => {
3682
3739
  aiCommon();
3683
3740
  jmxAi();
3684
3741
  };
3685
- import_react19.configManager.addProductInfo("Hawtio AI Plugin", "0.2.0");
3742
+ import_react17.configManager.addProductInfo("Hawtio AI Plugin", "0.2.2");
3686
3743
  // Annotate the CommonJS export names for ESM import in node:
3687
3744
  0 && (module.exports = {
3688
3745
  plugin