@hawtio/ai-plugin 0.2.2 → 0.3.0

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
@@ -8,9 +8,6 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
8
  var __esm = (fn, res) => function __init() {
9
9
  return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
10
  };
11
- var __commonJS = (cb, mod) => function __require() {
12
- return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
13
- };
14
11
  var __export = (target, all) => {
15
12
  for (var name in all)
16
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -33,6 +30,25 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
33
30
  ));
34
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
35
32
 
33
+ // src/ai-plugin/chat/globals.ts
34
+ var import_react, pluginName, pluginTitle, pluginPath, log;
35
+ var init_globals = __esm({
36
+ "src/ai-plugin/chat/globals.ts"() {
37
+ "use strict";
38
+ import_react = require("@hawtio/react");
39
+ pluginName = "hawtio-ai-chat";
40
+ pluginTitle = "AI Chat";
41
+ pluginPath = "/ai-chat";
42
+ log = import_react.Logger.get(pluginName);
43
+ }
44
+ });
45
+
46
+ // src/ai-plugin/chat/Chat.css
47
+ var init_Chat = __esm({
48
+ "src/ai-plugin/chat/Chat.css"() {
49
+ }
50
+ });
51
+
36
52
  // src/ai-plugin/common/ai-model.ts
37
53
  var PROVIDERS, MODELS;
38
54
  var init_ai_model = __esm({
@@ -67,22 +83,282 @@ var init_ai_model = __esm({
67
83
  }
68
84
  });
69
85
 
70
- // src/ai-plugin/jmx-ai/globals.ts
71
- var import_react, pluginName, pluginTitle, pluginPath, log, PARAM_KEY_NODE_ID;
72
- var init_globals = __esm({
73
- "src/ai-plugin/jmx-ai/globals.ts"() {
86
+ // src/ai-plugin/common/ai-preferences-service.ts
87
+ var STORAGE_KEY_PREFERENCES, DEFAULT_TOOL_PERMISSIONS, DEFAULT_MAX_AUTO_TOOL_STEPS, DEFAULT_OPTIONS, AiPreferencesService, aiPreferencesService;
88
+ var init_ai_preferences_service = __esm({
89
+ "src/ai-plugin/common/ai-preferences-service.ts"() {
74
90
  "use strict";
75
- import_react = require("@hawtio/react");
76
- pluginName = "hawtio-ai-jmx-ai";
77
- pluginTitle = "JMX AI";
78
- pluginPath = "/jmx-ai";
79
- log = import_react.Logger.get(pluginName);
80
- PARAM_KEY_NODE_ID = "nid";
91
+ init_ai_model();
92
+ init_ai_service();
93
+ STORAGE_KEY_PREFERENCES = "ai.preferences";
94
+ DEFAULT_TOOL_PERMISSIONS = {
95
+ listMBeans: true,
96
+ getMBeanInfo: true,
97
+ searchMBeans: true,
98
+ readMBeanAttribute: false,
99
+ writeMBeanAttribute: false,
100
+ executeMBeanOperation: false
101
+ };
102
+ DEFAULT_MAX_AUTO_TOOL_STEPS = 10;
103
+ DEFAULT_OPTIONS = {
104
+ model: MODELS[0],
105
+ toolPermissions: DEFAULT_TOOL_PERMISSIONS,
106
+ maxAutoToolSteps: DEFAULT_MAX_AUTO_TOOL_STEPS
107
+ };
108
+ AiPreferencesService = class {
109
+ loadOptions() {
110
+ const item = localStorage.getItem(STORAGE_KEY_PREFERENCES);
111
+ const savedOptions = item ? JSON.parse(item) : {};
112
+ return { ...DEFAULT_OPTIONS, ...savedOptions };
113
+ }
114
+ saveOptions(options) {
115
+ const updated = { ...this.loadOptions(), ...options };
116
+ localStorage.setItem(STORAGE_KEY_PREFERENCES, JSON.stringify(updated));
117
+ if (options.model) {
118
+ aiService.reset(options.model);
119
+ }
120
+ }
121
+ };
122
+ aiPreferencesService = new AiPreferencesService();
123
+ }
124
+ });
125
+
126
+ // src/ai-plugin/common/globals.ts
127
+ var import_react2, pluginName2, pluginTitle2, log2;
128
+ var init_globals2 = __esm({
129
+ "src/ai-plugin/common/globals.ts"() {
130
+ "use strict";
131
+ import_react2 = require("@hawtio/react");
132
+ pluginName2 = "hawtio-ai";
133
+ pluginTitle2 = "AI";
134
+ log2 = import_react2.Logger.get(pluginName2);
135
+ }
136
+ });
137
+
138
+ // src/ai-plugin/common/workspace.ts
139
+ var import_react3, WorkspaceExtension, workspaceExtension;
140
+ var init_workspace = __esm({
141
+ "src/ai-plugin/common/workspace.ts"() {
142
+ "use strict";
143
+ import_react3 = require("@hawtio/react");
144
+ init_globals2();
145
+ WorkspaceExtension = class {
146
+ constructor(workspace5, jolokiaService3) {
147
+ this.workspace = workspace5;
148
+ this.jolokiaService = jolokiaService3;
149
+ }
150
+ workspace;
151
+ jolokiaService;
152
+ async listMBeans() {
153
+ log2.debug("workspace - listMBeans called");
154
+ const tree = await this.workspace.getTree();
155
+ const flat = tree.flatten();
156
+ const result = Object.keys(flat).sort();
157
+ log2.debug("workspace - listMBeans result count:", result.length);
158
+ return result;
159
+ }
160
+ async getMBeanInfo(objectName) {
161
+ log2.debug("workspace - getMBeanInfo called:", objectName);
162
+ const tree = await this.workspace.getTree();
163
+ const flat = tree.flatten();
164
+ const mbeanInfo = flat[objectName]?.mbean ?? null;
165
+ if (!mbeanInfo) {
166
+ log2.debug("workspace - getMBeanInfo: not found:", objectName);
167
+ }
168
+ return mbeanInfo;
169
+ }
170
+ async readMBeanAttribute(objectName, attribute) {
171
+ log2.debug("workspace - readMBeanAttribute called:", objectName, attribute);
172
+ return this.jolokiaService.readAttribute(objectName, attribute);
173
+ }
174
+ async writeMBeanAttribute(objectName, attribute, value) {
175
+ log2.debug("workspace - writeMBeanAttribute called:", objectName, attribute, value);
176
+ return this.jolokiaService.writeAttribute(objectName, attribute, value);
177
+ }
178
+ async executeMBeanOperation(objectName, operation, args) {
179
+ log2.debug("workspace - executeMBeanOperation called:", objectName, operation, args);
180
+ return this.jolokiaService.execute(objectName, operation, args);
181
+ }
182
+ };
183
+ workspaceExtension = new WorkspaceExtension(import_react3.workspace, import_react3.jolokiaService);
184
+ }
185
+ });
186
+
187
+ // src/ai-plugin/common/tools.ts
188
+ function listMBeansTool() {
189
+ return new import_tools.DynamicStructuredTool({
190
+ name: "listMBeans",
191
+ description: `
192
+ List all MBean ObjectNames available in the Hawtio workspace cache.
193
+ Use this to discover what MBeans are present before querying details.
194
+ `,
195
+ schema: import_zod.z.object({}),
196
+ func: async () => {
197
+ log2.debug("tools - listMBeans called");
198
+ const result = await workspaceExtension.listMBeans();
199
+ return JSON.stringify(result);
200
+ }
201
+ });
202
+ }
203
+ function getMBeanInfoTool() {
204
+ return new import_tools.DynamicStructuredTool({
205
+ name: "getMBeanInfo",
206
+ description: `
207
+ Return the attribute schema (type, description, read/write flag) and operation definitions
208
+ (arguments, return type, description) for a specific MBean.
209
+ Call this before readMBeanAttribute or executeMBeanOperation to inspect available fields.
210
+ `,
211
+ schema: import_zod.z.object({
212
+ objectName: import_zod.z.string().describe("JMX ObjectName of the target MBean, e.g. 'java.lang:type=Memory'")
213
+ }),
214
+ func: async ({ objectName }) => {
215
+ log2.debug("tools - getMBeanInfo called:", objectName);
216
+ const info = await workspaceExtension.getMBeanInfo(objectName);
217
+ if (!info) {
218
+ return JSON.stringify({ error: `MBean not found: ${objectName}` });
219
+ }
220
+ return JSON.stringify({ objectName, attr: info.attr, op: info.op });
221
+ }
222
+ });
223
+ }
224
+ function searchMBeansTool() {
225
+ return new import_tools.DynamicStructuredTool({
226
+ name: "searchMBeans",
227
+ description: `
228
+ Search MBeans by JMX domain and property key/value pairs.
229
+ Returns a list of matching ObjectNames.
230
+ Use this to narrow down MBeans by type or name, e.g. domain='java.lang', properties='{"type":"Memory"}'.
231
+ `,
232
+ schema: import_zod.z.object({
233
+ domain: import_zod.z.string().describe("JMX domain to search in, e.g. 'java.lang'"),
234
+ properties: import_zod.z.string().describe(`JSON string of JMX property key/value pairs to match, e.g. '{"type":"Memory"}'`)
235
+ }),
236
+ func: async ({ domain, properties }) => {
237
+ log2.debug("tools - searchMBeans called:", domain, properties);
238
+ let parsed;
239
+ try {
240
+ parsed = JSON.parse(properties);
241
+ } catch {
242
+ return JSON.stringify({ error: `Invalid JSON for properties: ${properties}` });
243
+ }
244
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
245
+ return JSON.stringify({ error: `properties must be a JSON object, got: ${properties}` });
246
+ }
247
+ const nodes = await import_react4.workspace.findMBeans(domain, parsed);
248
+ const result = nodes.map((n) => n.objectName).filter((s) => s !== void 0);
249
+ log2.debug("tools - searchMBeans result count:", result.length);
250
+ return JSON.stringify(result);
251
+ }
252
+ });
253
+ }
254
+ function readMBeanAttributeTool() {
255
+ return new import_tools.DynamicStructuredTool({
256
+ name: "readMBeanAttribute",
257
+ description: `
258
+ Read the current value of an MBean attribute via Jolokia.
259
+ This is a read-only operation with no side effects.
260
+ Use getMBeanInfo first to confirm the attribute name and type.
261
+ `,
262
+ schema: import_zod.z.object({
263
+ objectName: import_zod.z.string().describe("ObjectName of the target MBean, e.g. 'java.lang:type=Memory'"),
264
+ attribute: import_zod.z.string().describe("Name of the attribute to read, e.g. 'HeapMemoryUsage'")
265
+ }),
266
+ func: async ({ objectName, attribute }) => {
267
+ log2.debug("tools - readMBeanAttribute called:", objectName, attribute);
268
+ try {
269
+ const value = await workspaceExtension.readMBeanAttribute(objectName, attribute);
270
+ return JSON.stringify({ objectName, attribute, value });
271
+ } catch (e) {
272
+ return JSON.stringify({ error: String(e) });
273
+ }
274
+ }
275
+ });
276
+ }
277
+ function writeMBeanAttributeTool() {
278
+ return new import_tools.DynamicStructuredTool({
279
+ name: "writeMBeanAttribute",
280
+ description: `
281
+ Write a value to a writable MBean attribute via Jolokia.
282
+ Verify rw=true with getMBeanInfo before calling this tool.
283
+ `,
284
+ schema: import_zod.z.object({
285
+ objectName: import_zod.z.string().describe("ObjectName of the target MBean, e.g. 'java.lang:type=Memory'"),
286
+ attribute: import_zod.z.string().describe("Name of the attribute to write"),
287
+ value: import_zod.z.string().describe('JSON-encoded value to set, e.g. "42" or "true" or "\\"hello\\""')
288
+ }),
289
+ func: async ({ objectName, attribute, value }) => {
290
+ log2.debug("tools - writeMBeanAttribute called:", objectName, attribute, value);
291
+ let parsed;
292
+ try {
293
+ parsed = JSON.parse(value);
294
+ } catch {
295
+ parsed = value;
296
+ }
297
+ try {
298
+ const result = await workspaceExtension.writeMBeanAttribute(objectName, attribute, parsed);
299
+ return JSON.stringify({ objectName, attribute, result });
300
+ } catch (e) {
301
+ return JSON.stringify({ error: String(e) });
302
+ }
303
+ }
304
+ });
305
+ }
306
+ function executeMBeanOperationTool() {
307
+ return new import_tools.DynamicStructuredTool({
308
+ name: "executeMBeanOperation",
309
+ description: `
310
+ Execute an MBean operation via Jolokia.
311
+ Use getMBeanInfo to verify the operation signature before calling.
312
+ For overloaded operations include the signature, e.g. 'gc()'.
313
+ `,
314
+ schema: import_zod.z.object({
315
+ objectName: import_zod.z.string().describe("ObjectName of the target MBean, e.g. 'java.lang:type=Memory'"),
316
+ operation: import_zod.z.string().describe("Operation name to invoke, e.g. 'gc' or 'gc()'"),
317
+ args: import_zod.z.array(import_zod.z.string()).optional().describe('JSON-encoded arguments to pass to the operation, e.g. ["value1", "42"]')
318
+ }),
319
+ func: async ({ objectName, operation, args }) => {
320
+ log2.debug("tools - executeMBeanOperation called:", objectName, operation, args);
321
+ const parsedArgs = args?.map((a) => {
322
+ try {
323
+ return JSON.parse(a);
324
+ } catch {
325
+ return a;
326
+ }
327
+ });
328
+ try {
329
+ const result = await workspaceExtension.executeMBeanOperation(objectName, operation, parsedArgs);
330
+ return JSON.stringify({ objectName, operation, result });
331
+ } catch (e) {
332
+ return JSON.stringify({ error: String(e) });
333
+ }
334
+ }
335
+ });
336
+ }
337
+ function getWorkspaceTools() {
338
+ return [
339
+ listMBeansTool(),
340
+ getMBeanInfoTool(),
341
+ searchMBeansTool(),
342
+ readMBeanAttributeTool(),
343
+ writeMBeanAttributeTool(),
344
+ executeMBeanOperationTool()
345
+ ];
346
+ }
347
+ var import_react4, import_tools, import_zod, WORKSPACE_TOOLS_META;
348
+ var init_tools = __esm({
349
+ "src/ai-plugin/common/tools.ts"() {
350
+ "use strict";
351
+ import_react4 = require("@hawtio/react");
352
+ import_tools = require("@langchain/core/tools");
353
+ import_zod = require("zod");
354
+ init_globals2();
355
+ init_workspace();
356
+ WORKSPACE_TOOLS_META = getWorkspaceTools().map(({ name, description }) => ({ name, description }));
81
357
  }
82
358
  });
83
359
 
84
360
  // src/ai-plugin/common/ai-service.ts
85
- var import_anthropic, import_messages, import_google_genai, import_ollama, import_openai, import_patternfly_avatar, import_img_avatar_light, BOT_NAME, TOOLS, TOOLS_BY_NAME, AiService, aiService;
361
+ var import_anthropic, import_messages, import_google_genai, import_ollama, import_openai, import_patternfly_avatar, import_img_avatar_light, import_react5, BOT_NAME, TOOLS, TOOLS_BY_NAME, AiService, aiService;
86
362
  var init_ai_service = __esm({
87
363
  "src/ai-plugin/common/ai-service.ts"() {
88
364
  "use strict";
@@ -93,10 +369,12 @@ var init_ai_service = __esm({
93
369
  import_openai = require("@langchain/openai");
94
370
  import_patternfly_avatar = __toESM(require("@patternfly/chatbot/patternfly-docs/content/extensions/chatbot/examples/Messages/patternfly_avatar.jpg"));
95
371
  import_img_avatar_light = __toESM(require("@patternfly/react-core/dist/styles/assets/images/img_avatar-light.svg"));
96
- init_globals();
372
+ import_react5 = require("react");
97
373
  init_ai_preferences_service();
374
+ init_globals2();
375
+ init_tools();
98
376
  BOT_NAME = "Hawtio AI";
99
- TOOLS = [];
377
+ TOOLS = getWorkspaceTools();
100
378
  TOOLS_BY_NAME = TOOLS.reduce(
101
379
  (acc, tool) => {
102
380
  acc[tool.name] = tool;
@@ -109,11 +387,16 @@ var init_ai_service = __esm({
109
387
  llm;
110
388
  llmWithTools;
111
389
  memory = {};
390
+ appendToolMessages(messages, toolCalls, content) {
391
+ for (const call of toolCalls) {
392
+ messages.push(new import_messages.ToolMessage({ tool_call_id: call.id ?? call.name, content }));
393
+ }
394
+ }
112
395
  reset(model) {
113
396
  if (this.model && this.model.id === model.id && this.llm && (!model.tool || this.llmWithTools)) {
114
397
  return;
115
398
  }
116
- log.info("AI model to use:", model.id);
399
+ log2.info("AI model to use:", model.id);
117
400
  this.memory = {};
118
401
  const { token } = aiPreferencesService.loadOptions();
119
402
  this.model = model;
@@ -123,7 +406,6 @@ var init_ai_service = __esm({
123
406
  this.llm = new import_openai.ChatOpenAI({
124
407
  model: this.model.id,
125
408
  apiKey: token,
126
- temperature: 0,
127
409
  streaming: false
128
410
  });
129
411
  break;
@@ -151,7 +433,7 @@ var init_ai_service = __esm({
151
433
  });
152
434
  }
153
435
  } catch (error) {
154
- log.warn("Error initialising AI model:", error);
436
+ log2.warn("Error initialising AI model:", error);
155
437
  this.llm = void 0;
156
438
  }
157
439
  this.llmWithTools = void 0;
@@ -172,7 +454,7 @@ var init_ai_service = __esm({
172
454
  }
173
455
  async invoke(messages) {
174
456
  const llm = this.getLlm();
175
- log.debug("Chatting with", this.model?.id, ":", messages);
457
+ log2.debug("Chatting with", this.model?.id, ":", messages);
176
458
  try {
177
459
  let answer;
178
460
  if (!llm) {
@@ -180,24 +462,28 @@ var init_ai_service = __esm({
180
462
  }
181
463
  answer = await llm.invoke(messages);
182
464
  if (answer.tool_calls && answer.tool_calls.length > 0) {
183
- log.debug("\u{1F6E0}\uFE0F calls:", answer.tool_calls);
465
+ log2.debug("\u{1F6E0}\uFE0F calls:", answer.tool_calls);
184
466
  }
185
- log.debug("Answer:", answer);
467
+ log2.debug("Answer:", answer);
186
468
  return answer;
187
469
  } catch (error) {
188
- log.error("Error while chatting:", error);
470
+ log2.error("Error while chatting:", error);
189
471
  return String(error);
190
472
  }
191
473
  }
192
- newChat(dialogId, message, system) {
474
+ newChat(dialogId, initialMessage, onMessage) {
475
+ const { message, system } = initialMessage;
193
476
  if (system) {
194
477
  this.memory[dialogId] = [new import_messages.SystemMessage(system)];
195
478
  } else {
196
479
  this.memory[dialogId] = [];
197
480
  }
198
- return this.chat(dialogId, message);
481
+ return this.chat(dialogId, message, onMessage);
199
482
  }
200
- async chat(dialogId, message) {
483
+ hasToolCalls(answer) {
484
+ return typeof answer !== "string" && (answer.tool_calls?.length ?? 0) > 0;
485
+ }
486
+ async chat(dialogId, message, onMessage) {
201
487
  let messages = this.memory[dialogId];
202
488
  if (!messages) {
203
489
  messages = [];
@@ -208,10 +494,26 @@ var init_ai_service = __esm({
208
494
  if (typeof answer !== "string") {
209
495
  messages.push(answer);
210
496
  }
211
- log.debug("Current messages:", messages);
497
+ log2.debug("Current messages:", messages);
498
+ if (this.hasToolCalls(answer)) {
499
+ const { toolPermissions } = aiPreferencesService.loadOptions();
500
+ if (answer.tool_calls.every((call) => toolPermissions?.[call.name] === true)) {
501
+ onMessage?.(answer);
502
+ return this.invokeTools(dialogId, answer.tool_calls, onMessage);
503
+ }
504
+ }
212
505
  return answer;
213
506
  }
214
- async invokeTools(dialogId, toolCalls) {
507
+ /**
508
+ * Executes the given tool calls and invokes the LLM with the results.
509
+ * If the LLM responds with further tool calls that are all auto-approved,
510
+ * this method recurses (up to {@link maxAutoToolSteps} times) to continue
511
+ * the chain without interruption. Tool calls that are not auto-approved are
512
+ * returned as-is so the caller can decide to approve or reject them.
513
+ *
514
+ * @param step - Current recursion depth; used to enforce the step limit.
515
+ */
516
+ async invokeTools(dialogId, toolCalls, onMessage, step = 0) {
215
517
  if (!this.llmWithTools) {
216
518
  return "Tool invocation not supported";
217
519
  }
@@ -220,28 +522,60 @@ var init_ai_service = __esm({
220
522
  messages = [];
221
523
  this.memory[dialogId] = messages;
222
524
  }
223
- for (const call of toolCalls) {
224
- log.debug("\u{1F6E0}\uFE0F Call:", call.name, JSON.stringify(call.args));
225
- const selectedTool = TOOLS_BY_NAME[call.name];
226
- const toolAnswer = await selectedTool?.invoke(call);
227
- if (toolAnswer) {
228
- log.debug("\u{1F6E0}\uFE0F " + call.name + ":", toolAnswer);
229
- messages.push(toolAnswer);
230
- }
525
+ const { toolPermissions, maxAutoToolSteps } = aiPreferencesService.loadOptions();
526
+ if (step >= maxAutoToolSteps) {
527
+ const limitMessage = `Automatic tool-call step limit reached after ${maxAutoToolSteps} steps.`;
528
+ this.appendToolMessages(messages, toolCalls, limitMessage);
529
+ log2.warn(`Auto-tool execution stopped after ${maxAutoToolSteps} steps to prevent runaway execution.`);
530
+ return `Stopped after ${maxAutoToolSteps} automatic tool-call steps. You can increase the limit in Preferences.`;
231
531
  }
232
- const finalAnswer = await this.llmWithTools.invoke(messages);
233
- if (finalAnswer) {
234
- messages.push(finalAnswer);
532
+ try {
533
+ for (const call of toolCalls) {
534
+ log2.debug("\u{1F6E0}\uFE0F Call:", call.name, JSON.stringify(call.args));
535
+ const selectedTool = TOOLS_BY_NAME[call.name];
536
+ const toolAnswer = await selectedTool?.invoke(call);
537
+ if (toolAnswer) {
538
+ log2.debug("\u{1F6E0}\uFE0F " + call.name + ":", toolAnswer);
539
+ messages.push(toolAnswer);
540
+ }
541
+ }
542
+ const answer = await this.llmWithTools.invoke(messages);
543
+ if (answer) {
544
+ messages.push(answer);
545
+ }
546
+ log2.debug("Messages>>", messages);
547
+ if (this.hasToolCalls(answer) && answer.tool_calls.every((call) => toolPermissions?.[call.name] === true)) {
548
+ onMessage?.(answer);
549
+ return this.invokeTools(dialogId, answer.tool_calls, onMessage, step + 1);
550
+ }
551
+ return answer;
552
+ } catch (error) {
553
+ log2.error("Error while invoking tools:", error);
554
+ return String(error);
235
555
  }
236
- console.debug("Messages>>", messages);
237
- return finalAnswer;
556
+ }
557
+ rejectTools(dialogId, toolCalls) {
558
+ const messages = this.memory[dialogId];
559
+ if (!messages) return;
560
+ this.appendToolMessages(messages, toolCalls, "User rejected");
561
+ log2.debug(
562
+ "rejectTools - added rejection ToolMessages for:",
563
+ toolCalls.map((c) => c.name)
564
+ );
238
565
  }
239
566
  generateId() {
240
567
  return crypto.randomUUID();
241
568
  }
242
569
  createUserMessage(name, content) {
243
570
  const id = this.generateId();
244
- return { id, role: "user", content, name, avatar: import_img_avatar_light.default };
571
+ return {
572
+ id,
573
+ role: "user",
574
+ content,
575
+ name,
576
+ avatar: import_img_avatar_light.default,
577
+ timestamp: (/* @__PURE__ */ new Date()).toLocaleString()
578
+ };
245
579
  }
246
580
  createLoadingBotMessage() {
247
581
  const id = this.generateId();
@@ -250,6 +584,7 @@ var init_ai_service = __esm({
250
584
  role: "bot",
251
585
  name: BOT_NAME,
252
586
  avatar: import_patternfly_avatar.default,
587
+ avatarProps: { style: { fontSize: "90%" } },
253
588
  content: "API response goes here",
254
589
  isLoading: true
255
590
  };
@@ -261,9 +596,11 @@ var init_ai_service = __esm({
261
596
  role: "bot",
262
597
  name: BOT_NAME,
263
598
  avatar: import_patternfly_avatar.default,
599
+ avatarProps: { style: { fontSize: "90%" } },
264
600
  content,
265
601
  extraContent,
266
- isLoading: false
602
+ isLoading: false,
603
+ timestamp: (/* @__PURE__ */ new Date()).toLocaleString()
267
604
  };
268
605
  }
269
606
  extractThink(message) {
@@ -274,2850 +611,541 @@ var init_ai_service = __esm({
274
611
  }
275
612
  return { content, think };
276
613
  }
277
- toBotMessage(answer, thinkInfo, toolCallsInfo, toolCallsApprove) {
614
+ toBotMessage(answer, autoApproved, ThinkInfo2, ToolCallsInfo2, ToolCallsApprove2) {
278
615
  if (typeof answer === "string") {
279
- return aiService.createBotMessage(`Error: ${answer}`);
616
+ return this.createBotMessage(`Error: ${answer}`);
280
617
  }
281
618
  if (!answer.tool_calls || answer.tool_calls.length === 0) {
282
- const { content: content2, think } = aiService.extractThink(answer);
283
- const extraContent2 = think ? { beforeMainContent: thinkInfo(think) } : void 0;
284
- return aiService.createBotMessage(content2, extraContent2);
619
+ const { content: content2, think } = this.extractThink(answer);
620
+ const extraContent = think ? { beforeMainContent: (0, import_react5.createElement)(ThinkInfo2, { think }) } : void 0;
621
+ return this.createBotMessage(content2, extraContent);
285
622
  }
286
623
  const toolCalls = answer.tool_calls;
287
- const content = `${BOT_NAME} wants to use ` + (toolCalls.length > 1 ? "tools" : "a tool");
288
- const extraContent = {
289
- beforeMainContent: toolCalls.map(toolCallsInfo),
290
- afterMainContent: toolCallsApprove(toolCalls)
624
+ const isMultiple = toolCalls.length > 1;
625
+ const toolNames = toolCalls.map((call) => `**${call.name}**`).filter((name, index, self) => self.indexOf(name) === index).join(", ");
626
+ const beforeMainContent = toolCalls.map((call, index) => (0, import_react5.createElement)(ToolCallsInfo2, { key: index, call, index }));
627
+ if (autoApproved) {
628
+ const content2 = `Auto-approved ${toolCalls.length} tool ${isMultiple ? "calls" : "call"}: ${toolNames}`;
629
+ return this.createBotMessage(content2, { beforeMainContent });
630
+ }
631
+ const content = `${BOT_NAME} wants to use ${isMultiple ? "tools" : "a tool"}: ${toolNames}`;
632
+ const botMessage = this.createBotMessage(content);
633
+ botMessage.extraContent = {
634
+ beforeMainContent,
635
+ afterMainContent: (0, import_react5.createElement)(ToolCallsApprove2, { toolCalls, messageId: botMessage.id })
291
636
  };
292
- return aiService.createBotMessage(content, extraContent);
637
+ return botMessage;
293
638
  }
294
639
  };
295
640
  aiService = new AiService();
296
641
  }
297
642
  });
298
643
 
299
- // src/ai-plugin/common/ai-preferences-service.ts
300
- var STORAGE_KEY_PREFERENCES, DEFAULT_OPTIONS, AiPreferencesService, aiPreferencesService;
301
- var init_ai_preferences_service = __esm({
302
- "src/ai-plugin/common/ai-preferences-service.ts"() {
644
+ // src/ai-plugin/chat/model.ts
645
+ var ChatbotDialog;
646
+ var init_model = __esm({
647
+ "src/ai-plugin/chat/model.ts"() {
303
648
  "use strict";
304
- init_ai_model();
305
- init_ai_service();
306
- STORAGE_KEY_PREFERENCES = "ai.preferences";
307
- DEFAULT_OPTIONS = {
308
- model: MODELS[0]
309
- };
310
- AiPreferencesService = class {
311
- loadOptions() {
312
- const item = localStorage.getItem(STORAGE_KEY_PREFERENCES);
313
- const savedOptions = item ? JSON.parse(item) : {};
314
- return { ...DEFAULT_OPTIONS, ...savedOptions };
649
+ ChatbotDialog = class {
650
+ constructor(messages, summary) {
651
+ this.messages = messages;
652
+ this.summary = summary;
653
+ this.id = messages[0]?.id ?? "";
315
654
  }
316
- saveOptions(options) {
317
- const updated = { ...this.loadOptions(), ...options };
318
- localStorage.setItem(STORAGE_KEY_PREFERENCES, JSON.stringify(updated));
319
- if (options.model) {
320
- aiService.reset(options.model);
655
+ messages;
656
+ summary;
657
+ id;
658
+ setMessages(messages) {
659
+ if (messages[0]?.id !== this.id) {
660
+ throw new Error("Not the same dialog");
321
661
  }
662
+ this.messages = [...messages];
663
+ }
664
+ createConversation() {
665
+ const text = this.summary ?? (this.messages[0]?.content ?? "").substring(0, 20);
666
+ return { id: this.id, text };
322
667
  }
323
668
  };
324
- aiPreferencesService = new AiPreferencesService();
325
669
  }
326
670
  });
327
671
 
328
- // node_modules/react-is/cjs/react-is.production.min.js
329
- var require_react_is_production_min = __commonJS({
330
- "node_modules/react-is/cjs/react-is.production.min.js"(exports2) {
331
- "use strict";
332
- var b = "function" === typeof Symbol && Symbol.for;
333
- var c = b ? /* @__PURE__ */ Symbol.for("react.element") : 60103;
334
- var d = b ? /* @__PURE__ */ Symbol.for("react.portal") : 60106;
335
- var e = b ? /* @__PURE__ */ Symbol.for("react.fragment") : 60107;
336
- var f = b ? /* @__PURE__ */ Symbol.for("react.strict_mode") : 60108;
337
- var g = b ? /* @__PURE__ */ Symbol.for("react.profiler") : 60114;
338
- var h = b ? /* @__PURE__ */ Symbol.for("react.provider") : 60109;
339
- var k = b ? /* @__PURE__ */ Symbol.for("react.context") : 60110;
340
- var l = b ? /* @__PURE__ */ Symbol.for("react.async_mode") : 60111;
341
- var m = b ? /* @__PURE__ */ Symbol.for("react.concurrent_mode") : 60111;
342
- var n = b ? /* @__PURE__ */ Symbol.for("react.forward_ref") : 60112;
343
- var p = b ? /* @__PURE__ */ Symbol.for("react.suspense") : 60113;
344
- var q = b ? /* @__PURE__ */ Symbol.for("react.suspense_list") : 60120;
345
- var r = b ? /* @__PURE__ */ Symbol.for("react.memo") : 60115;
346
- var t = b ? /* @__PURE__ */ Symbol.for("react.lazy") : 60116;
347
- var v = b ? /* @__PURE__ */ Symbol.for("react.block") : 60121;
348
- var w = b ? /* @__PURE__ */ Symbol.for("react.fundamental") : 60117;
349
- var x = b ? /* @__PURE__ */ Symbol.for("react.responder") : 60118;
350
- var y = b ? /* @__PURE__ */ Symbol.for("react.scope") : 60119;
351
- function z(a) {
352
- if ("object" === typeof a && null !== a) {
353
- var u = a.$$typeof;
354
- switch (u) {
355
- case c:
356
- switch (a = a.type, a) {
357
- case l:
358
- case m:
359
- case e:
360
- case g:
361
- case f:
362
- case p:
363
- return a;
364
- default:
365
- switch (a = a && a.$$typeof, a) {
366
- case k:
367
- case n:
368
- case t:
369
- case r:
370
- case h:
371
- return a;
372
- default:
373
- return u;
374
- }
375
- }
376
- case d:
377
- return u;
378
- }
379
- }
672
+ // src/ai-plugin/chat/context.ts
673
+ function useChatbot() {
674
+ const [messages, setMessages] = (0, import_react6.useState)([]);
675
+ const [dialogs, setDialogs] = (0, import_react6.useState)([]);
676
+ const [conversations, setConversations] = (0, import_react6.useState)([]);
677
+ const [announcement, setAnnouncement] = (0, import_react6.useState)("");
678
+ const [isChatbotOpen, setIsChatbotOpen] = (0, import_react6.useState)(false);
679
+ const [isSendButtonDisabled, setIsSendButtonDisabled] = (0, import_react6.useState)(false);
680
+ const updateConversations = (messages2, summary) => {
681
+ const dialogId = messages2[0]?.id;
682
+ if (!dialogId) {
683
+ return;
380
684
  }
381
- function A(a) {
382
- return z(a) === m;
685
+ setMessages(messages2);
686
+ let dialog = dialogs.find((d) => d.id === dialogId);
687
+ if (dialog) {
688
+ dialog.setMessages(messages2);
689
+ } else {
690
+ dialog = new ChatbotDialog(messages2, summary);
691
+ dialogs.push(dialog);
383
692
  }
384
- exports2.AsyncMode = l;
385
- exports2.ConcurrentMode = m;
386
- exports2.ContextConsumer = k;
387
- exports2.ContextProvider = h;
388
- exports2.Element = c;
389
- exports2.ForwardRef = n;
390
- exports2.Fragment = e;
391
- exports2.Lazy = t;
392
- exports2.Memo = r;
393
- exports2.Portal = d;
394
- exports2.Profiler = g;
395
- exports2.StrictMode = f;
396
- exports2.Suspense = p;
397
- exports2.isAsyncMode = function(a) {
398
- return A(a) || z(a) === l;
399
- };
400
- exports2.isConcurrentMode = A;
401
- exports2.isContextConsumer = function(a) {
402
- return z(a) === k;
403
- };
404
- exports2.isContextProvider = function(a) {
405
- return z(a) === h;
406
- };
407
- exports2.isElement = function(a) {
408
- return "object" === typeof a && null !== a && a.$$typeof === c;
409
- };
410
- exports2.isForwardRef = function(a) {
411
- return z(a) === n;
412
- };
413
- exports2.isFragment = function(a) {
414
- return z(a) === e;
415
- };
416
- exports2.isLazy = function(a) {
417
- return z(a) === t;
418
- };
419
- exports2.isMemo = function(a) {
420
- return z(a) === r;
421
- };
422
- exports2.isPortal = function(a) {
423
- return z(a) === d;
424
- };
425
- exports2.isProfiler = function(a) {
426
- return z(a) === g;
427
- };
428
- exports2.isStrictMode = function(a) {
429
- return z(a) === f;
430
- };
431
- exports2.isSuspense = function(a) {
432
- return z(a) === p;
433
- };
434
- exports2.isValidElementType = function(a) {
435
- return "string" === typeof a || "function" === typeof a || a === e || a === m || a === g || a === f || a === p || a === q || "object" === typeof a && null !== a && (a.$$typeof === t || a.$$typeof === r || a.$$typeof === h || a.$$typeof === k || a.$$typeof === n || a.$$typeof === w || a.$$typeof === x || a.$$typeof === y || a.$$typeof === v);
436
- };
437
- exports2.typeOf = z;
693
+ setDialogs([...dialogs]);
694
+ log.debug("Updated dialogs:", dialogs);
695
+ if (!conversations.some((c) => c.id === dialogId)) {
696
+ const conversation = dialog.createConversation();
697
+ conversations.push(conversation);
698
+ setConversations([...conversations]);
699
+ log.debug("Updated conversations:", conversations);
700
+ }
701
+ };
702
+ return {
703
+ messages,
704
+ setMessages,
705
+ dialogs,
706
+ setDialogs,
707
+ conversations,
708
+ setConversations,
709
+ announcement,
710
+ setAnnouncement,
711
+ isChatbotOpen,
712
+ setIsChatbotOpen,
713
+ isSendButtonDisabled,
714
+ setIsSendButtonDisabled,
715
+ updateConversations
716
+ };
717
+ }
718
+ var import_react6, ChatbotContext;
719
+ var init_context = __esm({
720
+ "src/ai-plugin/chat/context.ts"() {
721
+ "use strict";
722
+ import_react6 = require("react");
723
+ init_globals();
724
+ init_model();
725
+ ChatbotContext = (0, import_react6.createContext)({
726
+ messages: [],
727
+ setMessages: () => {
728
+ },
729
+ dialogs: [],
730
+ setDialogs: () => {
731
+ },
732
+ conversations: [],
733
+ setConversations: () => {
734
+ },
735
+ announcement: "",
736
+ setAnnouncement: () => {
737
+ },
738
+ isChatbotOpen: false,
739
+ setIsChatbotOpen: () => {
740
+ },
741
+ isSendButtonDisabled: false,
742
+ setIsSendButtonDisabled: () => {
743
+ },
744
+ updateConversations: () => {
745
+ }
746
+ });
438
747
  }
439
748
  });
440
749
 
441
- // node_modules/react-is/cjs/react-is.development.js
442
- var require_react_is_development = __commonJS({
443
- "node_modules/react-is/cjs/react-is.development.js"(exports2) {
750
+ // src/ai-plugin/chat/ThinkInfo.tsx
751
+ var import_MarkdownContent, import_react_core, import_jsx_runtime, ThinkInfo;
752
+ var init_ThinkInfo = __esm({
753
+ "src/ai-plugin/chat/ThinkInfo.tsx"() {
444
754
  "use strict";
445
- if (process.env.NODE_ENV !== "production") {
446
- (function() {
447
- "use strict";
448
- var hasSymbol = typeof Symbol === "function" && Symbol.for;
449
- var REACT_ELEMENT_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.element") : 60103;
450
- var REACT_PORTAL_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.portal") : 60106;
451
- var REACT_FRAGMENT_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.fragment") : 60107;
452
- var REACT_STRICT_MODE_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.strict_mode") : 60108;
453
- var REACT_PROFILER_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.profiler") : 60114;
454
- var REACT_PROVIDER_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.provider") : 60109;
455
- var REACT_CONTEXT_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.context") : 60110;
456
- var REACT_ASYNC_MODE_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.async_mode") : 60111;
457
- var REACT_CONCURRENT_MODE_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.concurrent_mode") : 60111;
458
- var REACT_FORWARD_REF_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.forward_ref") : 60112;
459
- var REACT_SUSPENSE_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.suspense") : 60113;
460
- var REACT_SUSPENSE_LIST_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.suspense_list") : 60120;
461
- var REACT_MEMO_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.memo") : 60115;
462
- var REACT_LAZY_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.lazy") : 60116;
463
- var REACT_BLOCK_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.block") : 60121;
464
- var REACT_FUNDAMENTAL_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.fundamental") : 60117;
465
- var REACT_RESPONDER_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.responder") : 60118;
466
- var REACT_SCOPE_TYPE = hasSymbol ? /* @__PURE__ */ Symbol.for("react.scope") : 60119;
467
- function isValidElementType(type) {
468
- return typeof type === "string" || typeof type === "function" || // Note: its typeof might be other than 'symbol' or 'number' if it's a polyfill.
469
- type === REACT_FRAGMENT_TYPE || type === REACT_CONCURRENT_MODE_TYPE || type === REACT_PROFILER_TYPE || type === REACT_STRICT_MODE_TYPE || type === REACT_SUSPENSE_TYPE || type === REACT_SUSPENSE_LIST_TYPE || typeof type === "object" && type !== null && (type.$$typeof === REACT_LAZY_TYPE || type.$$typeof === REACT_MEMO_TYPE || type.$$typeof === REACT_PROVIDER_TYPE || type.$$typeof === REACT_CONTEXT_TYPE || type.$$typeof === REACT_FORWARD_REF_TYPE || type.$$typeof === REACT_FUNDAMENTAL_TYPE || type.$$typeof === REACT_RESPONDER_TYPE || type.$$typeof === REACT_SCOPE_TYPE || type.$$typeof === REACT_BLOCK_TYPE);
470
- }
471
- function typeOf(object) {
472
- if (typeof object === "object" && object !== null) {
473
- var $$typeof = object.$$typeof;
474
- switch ($$typeof) {
475
- case REACT_ELEMENT_TYPE:
476
- var type = object.type;
477
- switch (type) {
478
- case REACT_ASYNC_MODE_TYPE:
479
- case REACT_CONCURRENT_MODE_TYPE:
480
- case REACT_FRAGMENT_TYPE:
481
- case REACT_PROFILER_TYPE:
482
- case REACT_STRICT_MODE_TYPE:
483
- case REACT_SUSPENSE_TYPE:
484
- return type;
485
- default:
486
- var $$typeofType = type && type.$$typeof;
487
- switch ($$typeofType) {
488
- case REACT_CONTEXT_TYPE:
489
- case REACT_FORWARD_REF_TYPE:
490
- case REACT_LAZY_TYPE:
491
- case REACT_MEMO_TYPE:
492
- case REACT_PROVIDER_TYPE:
493
- return $$typeofType;
494
- default:
495
- return $$typeof;
496
- }
497
- }
498
- case REACT_PORTAL_TYPE:
499
- return $$typeof;
500
- }
501
- }
502
- return void 0;
503
- }
504
- var AsyncMode = REACT_ASYNC_MODE_TYPE;
505
- var ConcurrentMode = REACT_CONCURRENT_MODE_TYPE;
506
- var ContextConsumer = REACT_CONTEXT_TYPE;
507
- var ContextProvider = REACT_PROVIDER_TYPE;
508
- var Element = REACT_ELEMENT_TYPE;
509
- var ForwardRef = REACT_FORWARD_REF_TYPE;
510
- var Fragment2 = REACT_FRAGMENT_TYPE;
511
- var Lazy = REACT_LAZY_TYPE;
512
- var Memo = REACT_MEMO_TYPE;
513
- var Portal = REACT_PORTAL_TYPE;
514
- var Profiler = REACT_PROFILER_TYPE;
515
- var StrictMode = REACT_STRICT_MODE_TYPE;
516
- var Suspense = REACT_SUSPENSE_TYPE;
517
- var hasWarnedAboutDeprecatedIsAsyncMode = false;
518
- function isAsyncMode(object) {
519
- {
520
- if (!hasWarnedAboutDeprecatedIsAsyncMode) {
521
- hasWarnedAboutDeprecatedIsAsyncMode = true;
522
- console["warn"]("The ReactIs.isAsyncMode() alias has been deprecated, and will be removed in React 17+. Update your code to use ReactIs.isConcurrentMode() instead. It has the exact same API.");
523
- }
524
- }
525
- return isConcurrentMode(object) || typeOf(object) === REACT_ASYNC_MODE_TYPE;
526
- }
527
- function isConcurrentMode(object) {
528
- return typeOf(object) === REACT_CONCURRENT_MODE_TYPE;
529
- }
530
- function isContextConsumer(object) {
531
- return typeOf(object) === REACT_CONTEXT_TYPE;
532
- }
533
- function isContextProvider(object) {
534
- return typeOf(object) === REACT_PROVIDER_TYPE;
535
- }
536
- function isElement(object) {
537
- return typeof object === "object" && object !== null && object.$$typeof === REACT_ELEMENT_TYPE;
538
- }
539
- function isForwardRef(object) {
540
- return typeOf(object) === REACT_FORWARD_REF_TYPE;
541
- }
542
- function isFragment(object) {
543
- return typeOf(object) === REACT_FRAGMENT_TYPE;
544
- }
545
- function isLazy(object) {
546
- return typeOf(object) === REACT_LAZY_TYPE;
547
- }
548
- function isMemo(object) {
549
- return typeOf(object) === REACT_MEMO_TYPE;
550
- }
551
- function isPortal(object) {
552
- return typeOf(object) === REACT_PORTAL_TYPE;
553
- }
554
- function isProfiler(object) {
555
- return typeOf(object) === REACT_PROFILER_TYPE;
556
- }
557
- function isStrictMode(object) {
558
- return typeOf(object) === REACT_STRICT_MODE_TYPE;
559
- }
560
- function isSuspense(object) {
561
- return typeOf(object) === REACT_SUSPENSE_TYPE;
562
- }
563
- exports2.AsyncMode = AsyncMode;
564
- exports2.ConcurrentMode = ConcurrentMode;
565
- exports2.ContextConsumer = ContextConsumer;
566
- exports2.ContextProvider = ContextProvider;
567
- exports2.Element = Element;
568
- exports2.ForwardRef = ForwardRef;
569
- exports2.Fragment = Fragment2;
570
- exports2.Lazy = Lazy;
571
- exports2.Memo = Memo;
572
- exports2.Portal = Portal;
573
- exports2.Profiler = Profiler;
574
- exports2.StrictMode = StrictMode;
575
- exports2.Suspense = Suspense;
576
- exports2.isAsyncMode = isAsyncMode;
577
- exports2.isConcurrentMode = isConcurrentMode;
578
- exports2.isContextConsumer = isContextConsumer;
579
- exports2.isContextProvider = isContextProvider;
580
- exports2.isElement = isElement;
581
- exports2.isForwardRef = isForwardRef;
582
- exports2.isFragment = isFragment;
583
- exports2.isLazy = isLazy;
584
- exports2.isMemo = isMemo;
585
- exports2.isPortal = isPortal;
586
- exports2.isProfiler = isProfiler;
587
- exports2.isStrictMode = isStrictMode;
588
- exports2.isSuspense = isSuspense;
589
- exports2.isValidElementType = isValidElementType;
590
- exports2.typeOf = typeOf;
591
- })();
592
- }
755
+ import_MarkdownContent = __toESM(require("@patternfly/chatbot/dist/dynamic/MarkdownContent"));
756
+ import_react_core = require("@patternfly/react-core");
757
+ import_jsx_runtime = require("react/jsx-runtime");
758
+ ThinkInfo = ({ think }) => {
759
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.Alert, { variant: "info", title: "Thinking", isExpandable: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_MarkdownContent.default, { content: think }) });
760
+ };
593
761
  }
594
762
  });
595
763
 
596
- // node_modules/react-is/index.js
597
- var require_react_is = __commonJS({
598
- "node_modules/react-is/index.js"(exports2, module2) {
764
+ // src/ai-plugin/chat/ToolCallsInfo.tsx
765
+ var import_react_core2, import_wrench_icon, import_jsx_runtime2, ToolCallsInfo;
766
+ var init_ToolCallsInfo = __esm({
767
+ "src/ai-plugin/chat/ToolCallsInfo.tsx"() {
599
768
  "use strict";
600
- if (process.env.NODE_ENV === "production") {
601
- module2.exports = require_react_is_production_min();
602
- } else {
603
- module2.exports = require_react_is_development();
604
- }
605
- }
606
- });
607
-
608
- // node_modules/object-assign/index.js
609
- var require_object_assign = __commonJS({
610
- "node_modules/object-assign/index.js"(exports2, module2) {
611
- "use strict";
612
- var getOwnPropertySymbols = Object.getOwnPropertySymbols;
613
- var hasOwnProperty = Object.prototype.hasOwnProperty;
614
- var propIsEnumerable = Object.prototype.propertyIsEnumerable;
615
- function toObject(val) {
616
- if (val === null || val === void 0) {
617
- throw new TypeError("Object.assign cannot be called with null or undefined");
618
- }
619
- return Object(val);
620
- }
621
- function shouldUseNative() {
622
- try {
623
- if (!Object.assign) {
624
- return false;
625
- }
626
- var test1 = new String("abc");
627
- test1[5] = "de";
628
- if (Object.getOwnPropertyNames(test1)[0] === "5") {
629
- return false;
630
- }
631
- var test2 = {};
632
- for (var i = 0; i < 10; i++) {
633
- test2["_" + String.fromCharCode(i)] = i;
634
- }
635
- var order22 = Object.getOwnPropertyNames(test2).map(function(n) {
636
- return test2[n];
637
- });
638
- if (order22.join("") !== "0123456789") {
639
- return false;
640
- }
641
- var test3 = {};
642
- "abcdefghijklmnopqrst".split("").forEach(function(letter) {
643
- test3[letter] = letter;
644
- });
645
- if (Object.keys(Object.assign({}, test3)).join("") !== "abcdefghijklmnopqrst") {
646
- return false;
647
- }
648
- return true;
649
- } catch (err) {
650
- return false;
651
- }
652
- }
653
- module2.exports = shouldUseNative() ? Object.assign : function(target, source) {
654
- var from;
655
- var to = toObject(target);
656
- var symbols;
657
- for (var s = 1; s < arguments.length; s++) {
658
- from = Object(arguments[s]);
659
- for (var key in from) {
660
- if (hasOwnProperty.call(from, key)) {
661
- to[key] = from[key];
662
- }
663
- }
664
- if (getOwnPropertySymbols) {
665
- symbols = getOwnPropertySymbols(from);
666
- for (var i = 0; i < symbols.length; i++) {
667
- if (propIsEnumerable.call(from, symbols[i])) {
668
- to[symbols[i]] = from[symbols[i]];
669
- }
670
- }
671
- }
672
- }
673
- return to;
674
- };
675
- }
676
- });
677
-
678
- // node_modules/prop-types/lib/ReactPropTypesSecret.js
679
- var require_ReactPropTypesSecret = __commonJS({
680
- "node_modules/prop-types/lib/ReactPropTypesSecret.js"(exports2, module2) {
681
- "use strict";
682
- var ReactPropTypesSecret = "SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED";
683
- module2.exports = ReactPropTypesSecret;
684
- }
685
- });
686
-
687
- // node_modules/prop-types/lib/has.js
688
- var require_has = __commonJS({
689
- "node_modules/prop-types/lib/has.js"(exports2, module2) {
690
- "use strict";
691
- module2.exports = Function.call.bind(Object.prototype.hasOwnProperty);
692
- }
693
- });
694
-
695
- // node_modules/prop-types/checkPropTypes.js
696
- var require_checkPropTypes = __commonJS({
697
- "node_modules/prop-types/checkPropTypes.js"(exports2, module2) {
698
- "use strict";
699
- var printWarning = function() {
700
- };
701
- if (process.env.NODE_ENV !== "production") {
702
- ReactPropTypesSecret = require_ReactPropTypesSecret();
703
- loggedTypeFailures = {};
704
- has = require_has();
705
- printWarning = function(text) {
706
- var message = "Warning: " + text;
707
- if (typeof console !== "undefined") {
708
- console.error(message);
709
- }
710
- try {
711
- throw new Error(message);
712
- } catch (x) {
713
- }
714
- };
715
- }
716
- var ReactPropTypesSecret;
717
- var loggedTypeFailures;
718
- var has;
719
- function checkPropTypes(typeSpecs, values, location, componentName, getStack) {
720
- if (process.env.NODE_ENV !== "production") {
721
- for (var typeSpecName in typeSpecs) {
722
- if (has(typeSpecs, typeSpecName)) {
723
- var error;
724
- try {
725
- if (typeof typeSpecs[typeSpecName] !== "function") {
726
- var err = Error(
727
- (componentName || "React class") + ": " + location + " type `" + typeSpecName + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + typeof typeSpecs[typeSpecName] + "`.This often happens because of typos such as `PropTypes.function` instead of `PropTypes.func`."
728
- );
729
- err.name = "Invariant Violation";
730
- throw err;
731
- }
732
- error = typeSpecs[typeSpecName](values, typeSpecName, componentName, location, null, ReactPropTypesSecret);
733
- } catch (ex) {
734
- error = ex;
735
- }
736
- if (error && !(error instanceof Error)) {
737
- printWarning(
738
- (componentName || "React class") + ": type specification of " + location + " `" + typeSpecName + "` is invalid; the type checker function must return `null` or an `Error` but returned a " + typeof error + ". You may have forgotten to pass an argument to the type checker creator (arrayOf, instanceOf, objectOf, oneOf, oneOfType, and shape all require an argument)."
739
- );
740
- }
741
- if (error instanceof Error && !(error.message in loggedTypeFailures)) {
742
- loggedTypeFailures[error.message] = true;
743
- var stack = getStack ? getStack() : "";
744
- printWarning(
745
- "Failed " + location + " type: " + error.message + (stack != null ? stack : "")
746
- );
747
- }
748
- }
749
- }
750
- }
751
- }
752
- checkPropTypes.resetWarningCache = function() {
753
- if (process.env.NODE_ENV !== "production") {
754
- loggedTypeFailures = {};
755
- }
756
- };
757
- module2.exports = checkPropTypes;
758
- }
759
- });
760
-
761
- // node_modules/prop-types/factoryWithTypeCheckers.js
762
- var require_factoryWithTypeCheckers = __commonJS({
763
- "node_modules/prop-types/factoryWithTypeCheckers.js"(exports2, module2) {
764
- "use strict";
765
- var ReactIs = require_react_is();
766
- var assign = require_object_assign();
767
- var ReactPropTypesSecret = require_ReactPropTypesSecret();
768
- var has = require_has();
769
- var checkPropTypes = require_checkPropTypes();
770
- var printWarning = function() {
771
- };
772
- if (process.env.NODE_ENV !== "production") {
773
- printWarning = function(text) {
774
- var message = "Warning: " + text;
775
- if (typeof console !== "undefined") {
776
- console.error(message);
777
- }
778
- try {
779
- throw new Error(message);
780
- } catch (x) {
781
- }
782
- };
783
- }
784
- function emptyFunctionThatReturnsNull() {
785
- return null;
786
- }
787
- module2.exports = function(isValidElement, throwOnDirectAccess) {
788
- var ITERATOR_SYMBOL = typeof Symbol === "function" && Symbol.iterator;
789
- var FAUX_ITERATOR_SYMBOL = "@@iterator";
790
- function getIteratorFn(maybeIterable) {
791
- var iteratorFn = maybeIterable && (ITERATOR_SYMBOL && maybeIterable[ITERATOR_SYMBOL] || maybeIterable[FAUX_ITERATOR_SYMBOL]);
792
- if (typeof iteratorFn === "function") {
793
- return iteratorFn;
794
- }
795
- }
796
- var ANONYMOUS = "<<anonymous>>";
797
- var ReactPropTypes = {
798
- array: createPrimitiveTypeChecker("array"),
799
- bigint: createPrimitiveTypeChecker("bigint"),
800
- bool: createPrimitiveTypeChecker("boolean"),
801
- func: createPrimitiveTypeChecker("function"),
802
- number: createPrimitiveTypeChecker("number"),
803
- object: createPrimitiveTypeChecker("object"),
804
- string: createPrimitiveTypeChecker("string"),
805
- symbol: createPrimitiveTypeChecker("symbol"),
806
- any: createAnyTypeChecker(),
807
- arrayOf: createArrayOfTypeChecker,
808
- element: createElementTypeChecker(),
809
- elementType: createElementTypeTypeChecker(),
810
- instanceOf: createInstanceTypeChecker,
811
- node: createNodeChecker(),
812
- objectOf: createObjectOfTypeChecker,
813
- oneOf: createEnumTypeChecker,
814
- oneOfType: createUnionTypeChecker,
815
- shape: createShapeTypeChecker,
816
- exact: createStrictShapeTypeChecker
817
- };
818
- function is(x, y) {
819
- if (x === y) {
820
- return x !== 0 || 1 / x === 1 / y;
821
- } else {
822
- return x !== x && y !== y;
823
- }
824
- }
825
- function PropTypeError(message, data) {
826
- this.message = message;
827
- this.data = data && typeof data === "object" ? data : {};
828
- this.stack = "";
829
- }
830
- PropTypeError.prototype = Error.prototype;
831
- function createChainableTypeChecker(validate) {
832
- if (process.env.NODE_ENV !== "production") {
833
- var manualPropTypeCallCache = {};
834
- var manualPropTypeWarningCount = 0;
835
- }
836
- function checkType(isRequired, props, propName, componentName, location, propFullName, secret) {
837
- componentName = componentName || ANONYMOUS;
838
- propFullName = propFullName || propName;
839
- if (secret !== ReactPropTypesSecret) {
840
- if (throwOnDirectAccess) {
841
- var err = new Error(
842
- "Calling PropTypes validators directly is not supported by the `prop-types` package. Use `PropTypes.checkPropTypes()` to call them. Read more at http://fb.me/use-check-prop-types"
843
- );
844
- err.name = "Invariant Violation";
845
- throw err;
846
- } else if (process.env.NODE_ENV !== "production" && typeof console !== "undefined") {
847
- var cacheKey = componentName + ":" + propName;
848
- if (!manualPropTypeCallCache[cacheKey] && // Avoid spamming the console because they are often not actionable except for lib authors
849
- manualPropTypeWarningCount < 3) {
850
- printWarning(
851
- "You are manually calling a React.PropTypes validation function for the `" + propFullName + "` prop on `" + componentName + "`. This is deprecated and will throw in the standalone `prop-types` package. You may be seeing this warning due to a third-party PropTypes library. See https://fb.me/react-warning-dont-call-proptypes for details."
852
- );
853
- manualPropTypeCallCache[cacheKey] = true;
854
- manualPropTypeWarningCount++;
855
- }
856
- }
857
- }
858
- if (props[propName] == null) {
859
- if (isRequired) {
860
- if (props[propName] === null) {
861
- return new PropTypeError("The " + location + " `" + propFullName + "` is marked as required " + ("in `" + componentName + "`, but its value is `null`."));
862
- }
863
- return new PropTypeError("The " + location + " `" + propFullName + "` is marked as required in " + ("`" + componentName + "`, but its value is `undefined`."));
864
- }
865
- return null;
866
- } else {
867
- return validate(props, propName, componentName, location, propFullName);
868
- }
869
- }
870
- var chainedCheckType = checkType.bind(null, false);
871
- chainedCheckType.isRequired = checkType.bind(null, true);
872
- return chainedCheckType;
873
- }
874
- function createPrimitiveTypeChecker(expectedType) {
875
- function validate(props, propName, componentName, location, propFullName, secret) {
876
- var propValue = props[propName];
877
- var propType = getPropType(propValue);
878
- if (propType !== expectedType) {
879
- var preciseType = getPreciseType(propValue);
880
- return new PropTypeError(
881
- "Invalid " + location + " `" + propFullName + "` of type " + ("`" + preciseType + "` supplied to `" + componentName + "`, expected ") + ("`" + expectedType + "`."),
882
- { expectedType }
883
- );
884
- }
885
- return null;
886
- }
887
- return createChainableTypeChecker(validate);
888
- }
889
- function createAnyTypeChecker() {
890
- return createChainableTypeChecker(emptyFunctionThatReturnsNull);
891
- }
892
- function createArrayOfTypeChecker(typeChecker) {
893
- function validate(props, propName, componentName, location, propFullName) {
894
- if (typeof typeChecker !== "function") {
895
- return new PropTypeError("Property `" + propFullName + "` of component `" + componentName + "` has invalid PropType notation inside arrayOf.");
896
- }
897
- var propValue = props[propName];
898
- if (!Array.isArray(propValue)) {
899
- var propType = getPropType(propValue);
900
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type " + ("`" + propType + "` supplied to `" + componentName + "`, expected an array."));
901
- }
902
- for (var i = 0; i < propValue.length; i++) {
903
- var error = typeChecker(propValue, i, componentName, location, propFullName + "[" + i + "]", ReactPropTypesSecret);
904
- if (error instanceof Error) {
905
- return error;
906
- }
907
- }
908
- return null;
909
- }
910
- return createChainableTypeChecker(validate);
911
- }
912
- function createElementTypeChecker() {
913
- function validate(props, propName, componentName, location, propFullName) {
914
- var propValue = props[propName];
915
- if (!isValidElement(propValue)) {
916
- var propType = getPropType(propValue);
917
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type " + ("`" + propType + "` supplied to `" + componentName + "`, expected a single ReactElement."));
918
- }
919
- return null;
920
- }
921
- return createChainableTypeChecker(validate);
922
- }
923
- function createElementTypeTypeChecker() {
924
- function validate(props, propName, componentName, location, propFullName) {
925
- var propValue = props[propName];
926
- if (!ReactIs.isValidElementType(propValue)) {
927
- var propType = getPropType(propValue);
928
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type " + ("`" + propType + "` supplied to `" + componentName + "`, expected a single ReactElement type."));
929
- }
930
- return null;
931
- }
932
- return createChainableTypeChecker(validate);
933
- }
934
- function createInstanceTypeChecker(expectedClass) {
935
- function validate(props, propName, componentName, location, propFullName) {
936
- if (!(props[propName] instanceof expectedClass)) {
937
- var expectedClassName = expectedClass.name || ANONYMOUS;
938
- var actualClassName = getClassName(props[propName]);
939
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type " + ("`" + actualClassName + "` supplied to `" + componentName + "`, expected ") + ("instance of `" + expectedClassName + "`."));
940
- }
941
- return null;
942
- }
943
- return createChainableTypeChecker(validate);
944
- }
945
- function createEnumTypeChecker(expectedValues) {
946
- if (!Array.isArray(expectedValues)) {
947
- if (process.env.NODE_ENV !== "production") {
948
- if (arguments.length > 1) {
949
- printWarning(
950
- "Invalid arguments supplied to oneOf, expected an array, got " + arguments.length + " arguments. A common mistake is to write oneOf(x, y, z) instead of oneOf([x, y, z])."
951
- );
952
- } else {
953
- printWarning("Invalid argument supplied to oneOf, expected an array.");
954
- }
955
- }
956
- return emptyFunctionThatReturnsNull;
957
- }
958
- function validate(props, propName, componentName, location, propFullName) {
959
- var propValue = props[propName];
960
- for (var i = 0; i < expectedValues.length; i++) {
961
- if (is(propValue, expectedValues[i])) {
962
- return null;
963
- }
964
- }
965
- var valuesString = JSON.stringify(expectedValues, function replacer(key, value) {
966
- var type = getPreciseType(value);
967
- if (type === "symbol") {
968
- return String(value);
969
- }
970
- return value;
971
- });
972
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of value `" + String(propValue) + "` " + ("supplied to `" + componentName + "`, expected one of " + valuesString + "."));
973
- }
974
- return createChainableTypeChecker(validate);
975
- }
976
- function createObjectOfTypeChecker(typeChecker) {
977
- function validate(props, propName, componentName, location, propFullName) {
978
- if (typeof typeChecker !== "function") {
979
- return new PropTypeError("Property `" + propFullName + "` of component `" + componentName + "` has invalid PropType notation inside objectOf.");
980
- }
981
- var propValue = props[propName];
982
- var propType = getPropType(propValue);
983
- if (propType !== "object") {
984
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type " + ("`" + propType + "` supplied to `" + componentName + "`, expected an object."));
985
- }
986
- for (var key in propValue) {
987
- if (has(propValue, key)) {
988
- var error = typeChecker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret);
989
- if (error instanceof Error) {
990
- return error;
991
- }
992
- }
993
- }
994
- return null;
995
- }
996
- return createChainableTypeChecker(validate);
997
- }
998
- function createUnionTypeChecker(arrayOfTypeCheckers) {
999
- if (!Array.isArray(arrayOfTypeCheckers)) {
1000
- process.env.NODE_ENV !== "production" ? printWarning("Invalid argument supplied to oneOfType, expected an instance of array.") : void 0;
1001
- return emptyFunctionThatReturnsNull;
1002
- }
1003
- for (var i = 0; i < arrayOfTypeCheckers.length; i++) {
1004
- var checker = arrayOfTypeCheckers[i];
1005
- if (typeof checker !== "function") {
1006
- printWarning(
1007
- "Invalid argument supplied to oneOfType. Expected an array of check functions, but received " + getPostfixForTypeWarning(checker) + " at index " + i + "."
1008
- );
1009
- return emptyFunctionThatReturnsNull;
1010
- }
1011
- }
1012
- function validate(props, propName, componentName, location, propFullName) {
1013
- var expectedTypes = [];
1014
- for (var i2 = 0; i2 < arrayOfTypeCheckers.length; i2++) {
1015
- var checker2 = arrayOfTypeCheckers[i2];
1016
- var checkerResult = checker2(props, propName, componentName, location, propFullName, ReactPropTypesSecret);
1017
- if (checkerResult == null) {
1018
- return null;
1019
- }
1020
- if (checkerResult.data && has(checkerResult.data, "expectedType")) {
1021
- expectedTypes.push(checkerResult.data.expectedType);
1022
- }
1023
- }
1024
- var expectedTypesMessage = expectedTypes.length > 0 ? ", expected one of type [" + expectedTypes.join(", ") + "]" : "";
1025
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` supplied to " + ("`" + componentName + "`" + expectedTypesMessage + "."));
1026
- }
1027
- return createChainableTypeChecker(validate);
1028
- }
1029
- function createNodeChecker() {
1030
- function validate(props, propName, componentName, location, propFullName) {
1031
- if (!isNode(props[propName])) {
1032
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` supplied to " + ("`" + componentName + "`, expected a ReactNode."));
1033
- }
1034
- return null;
1035
- }
1036
- return createChainableTypeChecker(validate);
1037
- }
1038
- function invalidValidatorError(componentName, location, propFullName, key, type) {
1039
- return new PropTypeError(
1040
- (componentName || "React class") + ": " + location + " type `" + propFullName + "." + key + "` is invalid; it must be a function, usually from the `prop-types` package, but received `" + type + "`."
1041
- );
1042
- }
1043
- function createShapeTypeChecker(shapeTypes) {
1044
- function validate(props, propName, componentName, location, propFullName) {
1045
- var propValue = props[propName];
1046
- var propType = getPropType(propValue);
1047
- if (propType !== "object") {
1048
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + propType + "` " + ("supplied to `" + componentName + "`, expected `object`."));
1049
- }
1050
- for (var key in shapeTypes) {
1051
- var checker = shapeTypes[key];
1052
- if (typeof checker !== "function") {
1053
- return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));
1054
- }
1055
- var error = checker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret);
1056
- if (error) {
1057
- return error;
1058
- }
1059
- }
1060
- return null;
1061
- }
1062
- return createChainableTypeChecker(validate);
1063
- }
1064
- function createStrictShapeTypeChecker(shapeTypes) {
1065
- function validate(props, propName, componentName, location, propFullName) {
1066
- var propValue = props[propName];
1067
- var propType = getPropType(propValue);
1068
- if (propType !== "object") {
1069
- return new PropTypeError("Invalid " + location + " `" + propFullName + "` of type `" + propType + "` " + ("supplied to `" + componentName + "`, expected `object`."));
1070
- }
1071
- var allKeys = assign({}, props[propName], shapeTypes);
1072
- for (var key in allKeys) {
1073
- var checker = shapeTypes[key];
1074
- if (has(shapeTypes, key) && typeof checker !== "function") {
1075
- return invalidValidatorError(componentName, location, propFullName, key, getPreciseType(checker));
1076
- }
1077
- if (!checker) {
1078
- return new PropTypeError(
1079
- "Invalid " + location + " `" + propFullName + "` key `" + key + "` supplied to `" + componentName + "`.\nBad object: " + JSON.stringify(props[propName], null, " ") + "\nValid keys: " + JSON.stringify(Object.keys(shapeTypes), null, " ")
1080
- );
1081
- }
1082
- var error = checker(propValue, key, componentName, location, propFullName + "." + key, ReactPropTypesSecret);
1083
- if (error) {
1084
- return error;
1085
- }
1086
- }
1087
- return null;
1088
- }
1089
- return createChainableTypeChecker(validate);
1090
- }
1091
- function isNode(propValue) {
1092
- switch (typeof propValue) {
1093
- case "number":
1094
- case "string":
1095
- case "undefined":
1096
- return true;
1097
- case "boolean":
1098
- return !propValue;
1099
- case "object":
1100
- if (Array.isArray(propValue)) {
1101
- return propValue.every(isNode);
1102
- }
1103
- if (propValue === null || isValidElement(propValue)) {
1104
- return true;
1105
- }
1106
- var iteratorFn = getIteratorFn(propValue);
1107
- if (iteratorFn) {
1108
- var iterator = iteratorFn.call(propValue);
1109
- var step;
1110
- if (iteratorFn !== propValue.entries) {
1111
- while (!(step = iterator.next()).done) {
1112
- if (!isNode(step.value)) {
1113
- return false;
1114
- }
1115
- }
1116
- } else {
1117
- while (!(step = iterator.next()).done) {
1118
- var entry = step.value;
1119
- if (entry) {
1120
- if (!isNode(entry[1])) {
1121
- return false;
1122
- }
1123
- }
1124
- }
1125
- }
1126
- } else {
1127
- return false;
1128
- }
1129
- return true;
1130
- default:
1131
- return false;
1132
- }
1133
- }
1134
- function isSymbol(propType, propValue) {
1135
- if (propType === "symbol") {
1136
- return true;
1137
- }
1138
- if (!propValue) {
1139
- return false;
1140
- }
1141
- if (propValue["@@toStringTag"] === "Symbol") {
1142
- return true;
1143
- }
1144
- if (typeof Symbol === "function" && propValue instanceof Symbol) {
1145
- return true;
1146
- }
1147
- return false;
1148
- }
1149
- function getPropType(propValue) {
1150
- var propType = typeof propValue;
1151
- if (Array.isArray(propValue)) {
1152
- return "array";
1153
- }
1154
- if (propValue instanceof RegExp) {
1155
- return "object";
1156
- }
1157
- if (isSymbol(propType, propValue)) {
1158
- return "symbol";
1159
- }
1160
- return propType;
1161
- }
1162
- function getPreciseType(propValue) {
1163
- if (typeof propValue === "undefined" || propValue === null) {
1164
- return "" + propValue;
1165
- }
1166
- var propType = getPropType(propValue);
1167
- if (propType === "object") {
1168
- if (propValue instanceof Date) {
1169
- return "date";
1170
- } else if (propValue instanceof RegExp) {
1171
- return "regexp";
1172
- }
1173
- }
1174
- return propType;
1175
- }
1176
- function getPostfixForTypeWarning(value) {
1177
- var type = getPreciseType(value);
1178
- switch (type) {
1179
- case "array":
1180
- case "object":
1181
- return "an " + type;
1182
- case "boolean":
1183
- case "date":
1184
- case "regexp":
1185
- return "a " + type;
1186
- default:
1187
- return type;
1188
- }
1189
- }
1190
- function getClassName(propValue) {
1191
- if (!propValue.constructor || !propValue.constructor.name) {
1192
- return ANONYMOUS;
1193
- }
1194
- return propValue.constructor.name;
1195
- }
1196
- ReactPropTypes.checkPropTypes = checkPropTypes;
1197
- ReactPropTypes.resetWarningCache = checkPropTypes.resetWarningCache;
1198
- ReactPropTypes.PropTypes = ReactPropTypes;
1199
- return ReactPropTypes;
1200
- };
1201
- }
1202
- });
1203
-
1204
- // node_modules/prop-types/factoryWithThrowingShims.js
1205
- var require_factoryWithThrowingShims = __commonJS({
1206
- "node_modules/prop-types/factoryWithThrowingShims.js"(exports2, module2) {
1207
- "use strict";
1208
- var ReactPropTypesSecret = require_ReactPropTypesSecret();
1209
- function emptyFunction() {
1210
- }
1211
- function emptyFunctionWithReset() {
1212
- }
1213
- emptyFunctionWithReset.resetWarningCache = emptyFunction;
1214
- module2.exports = function() {
1215
- function shim(props, propName, componentName, location, propFullName, secret) {
1216
- if (secret === ReactPropTypesSecret) {
1217
- return;
1218
- }
1219
- var err = new Error(
1220
- "Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types"
1221
- );
1222
- err.name = "Invariant Violation";
1223
- throw err;
1224
- }
1225
- ;
1226
- shim.isRequired = shim;
1227
- function getShim() {
1228
- return shim;
1229
- }
1230
- ;
1231
- var ReactPropTypes = {
1232
- array: shim,
1233
- bigint: shim,
1234
- bool: shim,
1235
- func: shim,
1236
- number: shim,
1237
- object: shim,
1238
- string: shim,
1239
- symbol: shim,
1240
- any: shim,
1241
- arrayOf: getShim,
1242
- element: shim,
1243
- elementType: shim,
1244
- instanceOf: getShim,
1245
- node: shim,
1246
- objectOf: getShim,
1247
- oneOf: getShim,
1248
- oneOfType: getShim,
1249
- shape: getShim,
1250
- exact: getShim,
1251
- checkPropTypes: emptyFunctionWithReset,
1252
- resetWarningCache: emptyFunction
1253
- };
1254
- ReactPropTypes.PropTypes = ReactPropTypes;
1255
- return ReactPropTypes;
1256
- };
1257
- }
1258
- });
1259
-
1260
- // node_modules/prop-types/index.js
1261
- var require_prop_types = __commonJS({
1262
- "node_modules/prop-types/index.js"(exports2, module2) {
1263
- "use strict";
1264
- if (process.env.NODE_ENV !== "production") {
1265
- ReactIs = require_react_is();
1266
- throwOnDirectAccess = true;
1267
- module2.exports = require_factoryWithTypeCheckers()(ReactIs.isElement, throwOnDirectAccess);
1268
- } else {
1269
- module2.exports = require_factoryWithThrowingShims()();
1270
- }
1271
- var ReactIs;
1272
- var throwOnDirectAccess;
1273
- }
1274
- });
1275
-
1276
- // node_modules/split.js/dist/split.es.js
1277
- var global, ssr, document2, addEventListener, removeEventListener, getBoundingClientRect, gutterStartDragging, aGutterSize, bGutterSize, HORIZONTAL, NOOP, calc, isString, elementOrSelector, getOption, getGutterSize, defaultGutterFn, defaultElementStyleFn, defaultGutterStyleFn, Split, split_es_default;
1278
- var init_split_es = __esm({
1279
- "node_modules/split.js/dist/split.es.js"() {
1280
- "use strict";
1281
- global = typeof window !== "undefined" ? window : null;
1282
- ssr = global === null;
1283
- document2 = !ssr ? global.document : void 0;
1284
- addEventListener = "addEventListener";
1285
- removeEventListener = "removeEventListener";
1286
- getBoundingClientRect = "getBoundingClientRect";
1287
- gutterStartDragging = "_a";
1288
- aGutterSize = "_b";
1289
- bGutterSize = "_c";
1290
- HORIZONTAL = "horizontal";
1291
- NOOP = function() {
1292
- return false;
1293
- };
1294
- calc = ssr ? "calc" : ["", "-webkit-", "-moz-", "-o-"].filter(function(prefix) {
1295
- var el = document2.createElement("div");
1296
- el.style.cssText = "width:" + prefix + "calc(9px)";
1297
- return !!el.style.length;
1298
- }).shift() + "calc";
1299
- isString = function(v) {
1300
- return typeof v === "string" || v instanceof String;
1301
- };
1302
- elementOrSelector = function(el) {
1303
- if (isString(el)) {
1304
- var ele = document2.querySelector(el);
1305
- if (!ele) {
1306
- throw new Error("Selector " + el + " did not match a DOM element");
1307
- }
1308
- return ele;
1309
- }
1310
- return el;
1311
- };
1312
- getOption = function(options, propName, def) {
1313
- var value = options[propName];
1314
- if (value !== void 0) {
1315
- return value;
1316
- }
1317
- return def;
1318
- };
1319
- getGutterSize = function(gutterSize, isFirst, isLast, gutterAlign) {
1320
- if (isFirst) {
1321
- if (gutterAlign === "end") {
1322
- return 0;
1323
- }
1324
- if (gutterAlign === "center") {
1325
- return gutterSize / 2;
1326
- }
1327
- } else if (isLast) {
1328
- if (gutterAlign === "start") {
1329
- return 0;
1330
- }
1331
- if (gutterAlign === "center") {
1332
- return gutterSize / 2;
1333
- }
1334
- }
1335
- return gutterSize;
1336
- };
1337
- defaultGutterFn = function(i, gutterDirection) {
1338
- var gut = document2.createElement("div");
1339
- gut.className = "gutter gutter-" + gutterDirection;
1340
- return gut;
1341
- };
1342
- defaultElementStyleFn = function(dim, size, gutSize) {
1343
- var style = {};
1344
- if (!isString(size)) {
1345
- style[dim] = calc + "(" + size + "% - " + gutSize + "px)";
1346
- } else {
1347
- style[dim] = size;
1348
- }
1349
- return style;
1350
- };
1351
- defaultGutterStyleFn = function(dim, gutSize) {
1352
- var obj;
1353
- return obj = {}, obj[dim] = gutSize + "px", obj;
1354
- };
1355
- Split = function(idsOption, options) {
1356
- if (options === void 0) options = {};
1357
- if (ssr) {
1358
- return {};
1359
- }
1360
- var ids = idsOption;
1361
- var dimension;
1362
- var clientAxis;
1363
- var position;
1364
- var positionEnd;
1365
- var clientSize;
1366
- var elements;
1367
- if (Array.from) {
1368
- ids = Array.from(ids);
1369
- }
1370
- var firstElement = elementOrSelector(ids[0]);
1371
- var parent = firstElement.parentNode;
1372
- var parentStyle = getComputedStyle ? getComputedStyle(parent) : null;
1373
- var parentFlexDirection = parentStyle ? parentStyle.flexDirection : null;
1374
- var sizes = getOption(options, "sizes") || ids.map(function() {
1375
- return 100 / ids.length;
1376
- });
1377
- var minSize = getOption(options, "minSize", 100);
1378
- var minSizes = Array.isArray(minSize) ? minSize : ids.map(function() {
1379
- return minSize;
1380
- });
1381
- var maxSize = getOption(options, "maxSize", Infinity);
1382
- var maxSizes = Array.isArray(maxSize) ? maxSize : ids.map(function() {
1383
- return maxSize;
1384
- });
1385
- var expandToMin = getOption(options, "expandToMin", false);
1386
- var gutterSize = getOption(options, "gutterSize", 10);
1387
- var gutterAlign = getOption(options, "gutterAlign", "center");
1388
- var snapOffset = getOption(options, "snapOffset", 30);
1389
- var snapOffsets = Array.isArray(snapOffset) ? snapOffset : ids.map(function() {
1390
- return snapOffset;
1391
- });
1392
- var dragInterval = getOption(options, "dragInterval", 1);
1393
- var direction = getOption(options, "direction", HORIZONTAL);
1394
- var cursor = getOption(
1395
- options,
1396
- "cursor",
1397
- direction === HORIZONTAL ? "col-resize" : "row-resize"
1398
- );
1399
- var gutter = getOption(options, "gutter", defaultGutterFn);
1400
- var elementStyle = getOption(
1401
- options,
1402
- "elementStyle",
1403
- defaultElementStyleFn
1404
- );
1405
- var gutterStyle = getOption(options, "gutterStyle", defaultGutterStyleFn);
1406
- if (direction === HORIZONTAL) {
1407
- dimension = "width";
1408
- clientAxis = "clientX";
1409
- position = "left";
1410
- positionEnd = "right";
1411
- clientSize = "clientWidth";
1412
- } else if (direction === "vertical") {
1413
- dimension = "height";
1414
- clientAxis = "clientY";
1415
- position = "top";
1416
- positionEnd = "bottom";
1417
- clientSize = "clientHeight";
1418
- }
1419
- function setElementSize(el, size, gutSize, i) {
1420
- var style = elementStyle(dimension, size, gutSize, i);
1421
- Object.keys(style).forEach(function(prop) {
1422
- el.style[prop] = style[prop];
1423
- });
1424
- }
1425
- function setGutterSize(gutterElement, gutSize, i) {
1426
- var style = gutterStyle(dimension, gutSize, i);
1427
- Object.keys(style).forEach(function(prop) {
1428
- gutterElement.style[prop] = style[prop];
1429
- });
1430
- }
1431
- function getSizes() {
1432
- return elements.map(function(element) {
1433
- return element.size;
1434
- });
1435
- }
1436
- function getMousePosition(e) {
1437
- if ("touches" in e) {
1438
- return e.touches[0][clientAxis];
1439
- }
1440
- return e[clientAxis];
1441
- }
1442
- function adjust(offset) {
1443
- var a = elements[this.a];
1444
- var b = elements[this.b];
1445
- var percentage = a.size + b.size;
1446
- a.size = offset / this.size * percentage;
1447
- b.size = percentage - offset / this.size * percentage;
1448
- setElementSize(a.element, a.size, this[aGutterSize], a.i);
1449
- setElementSize(b.element, b.size, this[bGutterSize], b.i);
1450
- }
1451
- function drag(e) {
1452
- var offset;
1453
- var a = elements[this.a];
1454
- var b = elements[this.b];
1455
- if (!this.dragging) {
1456
- return;
1457
- }
1458
- offset = getMousePosition(e) - this.start + (this[aGutterSize] - this.dragOffset);
1459
- if (dragInterval > 1) {
1460
- offset = Math.round(offset / dragInterval) * dragInterval;
1461
- }
1462
- if (offset <= a.minSize + a.snapOffset + this[aGutterSize]) {
1463
- offset = a.minSize + this[aGutterSize];
1464
- } else if (offset >= this.size - (b.minSize + b.snapOffset + this[bGutterSize])) {
1465
- offset = this.size - (b.minSize + this[bGutterSize]);
1466
- }
1467
- if (offset >= a.maxSize - a.snapOffset + this[aGutterSize]) {
1468
- offset = a.maxSize + this[aGutterSize];
1469
- } else if (offset <= this.size - (b.maxSize - b.snapOffset + this[bGutterSize])) {
1470
- offset = this.size - (b.maxSize + this[bGutterSize]);
1471
- }
1472
- adjust.call(this, offset);
1473
- getOption(options, "onDrag", NOOP)(getSizes());
1474
- }
1475
- function calculateSizes() {
1476
- var a = elements[this.a].element;
1477
- var b = elements[this.b].element;
1478
- var aBounds = a[getBoundingClientRect]();
1479
- var bBounds = b[getBoundingClientRect]();
1480
- this.size = aBounds[dimension] + bBounds[dimension] + this[aGutterSize] + this[bGutterSize];
1481
- this.start = aBounds[position];
1482
- this.end = aBounds[positionEnd];
1483
- }
1484
- function innerSize(element) {
1485
- if (!getComputedStyle) {
1486
- return null;
1487
- }
1488
- var computedStyle = getComputedStyle(element);
1489
- if (!computedStyle) {
1490
- return null;
1491
- }
1492
- var size = element[clientSize];
1493
- if (size === 0) {
1494
- return null;
1495
- }
1496
- if (direction === HORIZONTAL) {
1497
- size -= parseFloat(computedStyle.paddingLeft) + parseFloat(computedStyle.paddingRight);
1498
- } else {
1499
- size -= parseFloat(computedStyle.paddingTop) + parseFloat(computedStyle.paddingBottom);
1500
- }
1501
- return size;
1502
- }
1503
- function trimToMin(sizesToTrim) {
1504
- var parentSize = innerSize(parent);
1505
- if (parentSize === null) {
1506
- return sizesToTrim;
1507
- }
1508
- if (minSizes.reduce(function(a, b) {
1509
- return a + b;
1510
- }, 0) > parentSize) {
1511
- return sizesToTrim;
1512
- }
1513
- var excessPixels = 0;
1514
- var toSpare = [];
1515
- var pixelSizes = sizesToTrim.map(function(size, i) {
1516
- var pixelSize = parentSize * size / 100;
1517
- var elementGutterSize = getGutterSize(
1518
- gutterSize,
1519
- i === 0,
1520
- i === sizesToTrim.length - 1,
1521
- gutterAlign
1522
- );
1523
- var elementMinSize = minSizes[i] + elementGutterSize;
1524
- if (pixelSize < elementMinSize) {
1525
- excessPixels += elementMinSize - pixelSize;
1526
- toSpare.push(0);
1527
- return elementMinSize;
1528
- }
1529
- toSpare.push(pixelSize - elementMinSize);
1530
- return pixelSize;
1531
- });
1532
- if (excessPixels === 0) {
1533
- return sizesToTrim;
1534
- }
1535
- return pixelSizes.map(function(pixelSize, i) {
1536
- var newPixelSize = pixelSize;
1537
- if (excessPixels > 0 && toSpare[i] - excessPixels > 0) {
1538
- var takenPixels = Math.min(
1539
- excessPixels,
1540
- toSpare[i] - excessPixels
1541
- );
1542
- excessPixels -= takenPixels;
1543
- newPixelSize = pixelSize - takenPixels;
1544
- }
1545
- return newPixelSize / parentSize * 100;
1546
- });
1547
- }
1548
- function stopDragging() {
1549
- var self = this;
1550
- var a = elements[self.a].element;
1551
- var b = elements[self.b].element;
1552
- if (self.dragging) {
1553
- getOption(options, "onDragEnd", NOOP)(getSizes());
1554
- }
1555
- self.dragging = false;
1556
- global[removeEventListener]("mouseup", self.stop);
1557
- global[removeEventListener]("touchend", self.stop);
1558
- global[removeEventListener]("touchcancel", self.stop);
1559
- global[removeEventListener]("mousemove", self.move);
1560
- global[removeEventListener]("touchmove", self.move);
1561
- self.stop = null;
1562
- self.move = null;
1563
- a[removeEventListener]("selectstart", NOOP);
1564
- a[removeEventListener]("dragstart", NOOP);
1565
- b[removeEventListener]("selectstart", NOOP);
1566
- b[removeEventListener]("dragstart", NOOP);
1567
- a.style.userSelect = "";
1568
- a.style.webkitUserSelect = "";
1569
- a.style.MozUserSelect = "";
1570
- a.style.pointerEvents = "";
1571
- b.style.userSelect = "";
1572
- b.style.webkitUserSelect = "";
1573
- b.style.MozUserSelect = "";
1574
- b.style.pointerEvents = "";
1575
- self.gutter.style.cursor = "";
1576
- self.parent.style.cursor = "";
1577
- document2.body.style.cursor = "";
1578
- }
1579
- function startDragging(e) {
1580
- if ("button" in e && e.button !== 0) {
1581
- return;
1582
- }
1583
- var self = this;
1584
- var a = elements[self.a].element;
1585
- var b = elements[self.b].element;
1586
- if (!self.dragging) {
1587
- getOption(options, "onDragStart", NOOP)(getSizes());
1588
- }
1589
- e.preventDefault();
1590
- self.dragging = true;
1591
- self.move = drag.bind(self);
1592
- self.stop = stopDragging.bind(self);
1593
- global[addEventListener]("mouseup", self.stop);
1594
- global[addEventListener]("touchend", self.stop);
1595
- global[addEventListener]("touchcancel", self.stop);
1596
- global[addEventListener]("mousemove", self.move);
1597
- global[addEventListener]("touchmove", self.move);
1598
- a[addEventListener]("selectstart", NOOP);
1599
- a[addEventListener]("dragstart", NOOP);
1600
- b[addEventListener]("selectstart", NOOP);
1601
- b[addEventListener]("dragstart", NOOP);
1602
- a.style.userSelect = "none";
1603
- a.style.webkitUserSelect = "none";
1604
- a.style.MozUserSelect = "none";
1605
- a.style.pointerEvents = "none";
1606
- b.style.userSelect = "none";
1607
- b.style.webkitUserSelect = "none";
1608
- b.style.MozUserSelect = "none";
1609
- b.style.pointerEvents = "none";
1610
- self.gutter.style.cursor = cursor;
1611
- self.parent.style.cursor = cursor;
1612
- document2.body.style.cursor = cursor;
1613
- calculateSizes.call(self);
1614
- self.dragOffset = getMousePosition(e) - self.end;
1615
- }
1616
- sizes = trimToMin(sizes);
1617
- var pairs = [];
1618
- elements = ids.map(function(id, i) {
1619
- var element = {
1620
- element: elementOrSelector(id),
1621
- size: sizes[i],
1622
- minSize: minSizes[i],
1623
- maxSize: maxSizes[i],
1624
- snapOffset: snapOffsets[i],
1625
- i
1626
- };
1627
- var pair;
1628
- if (i > 0) {
1629
- pair = {
1630
- a: i - 1,
1631
- b: i,
1632
- dragging: false,
1633
- direction,
1634
- parent
1635
- };
1636
- pair[aGutterSize] = getGutterSize(
1637
- gutterSize,
1638
- i - 1 === 0,
1639
- false,
1640
- gutterAlign
1641
- );
1642
- pair[bGutterSize] = getGutterSize(
1643
- gutterSize,
1644
- false,
1645
- i === ids.length - 1,
1646
- gutterAlign
1647
- );
1648
- if (parentFlexDirection === "row-reverse" || parentFlexDirection === "column-reverse") {
1649
- var temp = pair.a;
1650
- pair.a = pair.b;
1651
- pair.b = temp;
1652
- }
1653
- }
1654
- if (i > 0) {
1655
- var gutterElement = gutter(i, direction, element.element);
1656
- setGutterSize(gutterElement, gutterSize, i);
1657
- pair[gutterStartDragging] = startDragging.bind(pair);
1658
- gutterElement[addEventListener](
1659
- "mousedown",
1660
- pair[gutterStartDragging]
1661
- );
1662
- gutterElement[addEventListener](
1663
- "touchstart",
1664
- pair[gutterStartDragging]
1665
- );
1666
- parent.insertBefore(gutterElement, element.element);
1667
- pair.gutter = gutterElement;
1668
- }
1669
- setElementSize(
1670
- element.element,
1671
- element.size,
1672
- getGutterSize(
1673
- gutterSize,
1674
- i === 0,
1675
- i === ids.length - 1,
1676
- gutterAlign
1677
- ),
1678
- i
1679
- );
1680
- if (i > 0) {
1681
- pairs.push(pair);
1682
- }
1683
- return element;
1684
- });
1685
- function adjustToMin(element) {
1686
- var isLast = element.i === pairs.length;
1687
- var pair = isLast ? pairs[element.i - 1] : pairs[element.i];
1688
- calculateSizes.call(pair);
1689
- var size = isLast ? pair.size - element.minSize - pair[bGutterSize] : element.minSize + pair[aGutterSize];
1690
- adjust.call(pair, size);
1691
- }
1692
- elements.forEach(function(element) {
1693
- var computedSize = element.element[getBoundingClientRect]()[dimension];
1694
- if (computedSize < element.minSize) {
1695
- if (expandToMin) {
1696
- adjustToMin(element);
1697
- } else {
1698
- element.minSize = computedSize;
1699
- }
1700
- }
1701
- });
1702
- function setSizes(newSizes) {
1703
- var trimmed = trimToMin(newSizes);
1704
- trimmed.forEach(function(newSize, i) {
1705
- if (i > 0) {
1706
- var pair = pairs[i - 1];
1707
- var a = elements[pair.a];
1708
- var b = elements[pair.b];
1709
- a.size = trimmed[i - 1];
1710
- b.size = newSize;
1711
- setElementSize(a.element, a.size, pair[aGutterSize], a.i);
1712
- setElementSize(b.element, b.size, pair[bGutterSize], b.i);
1713
- }
1714
- });
1715
- }
1716
- function destroy(preserveStyles, preserveGutter) {
1717
- pairs.forEach(function(pair) {
1718
- if (preserveGutter !== true) {
1719
- pair.parent.removeChild(pair.gutter);
1720
- } else {
1721
- pair.gutter[removeEventListener](
1722
- "mousedown",
1723
- pair[gutterStartDragging]
1724
- );
1725
- pair.gutter[removeEventListener](
1726
- "touchstart",
1727
- pair[gutterStartDragging]
1728
- );
1729
- }
1730
- if (preserveStyles !== true) {
1731
- var style = elementStyle(
1732
- dimension,
1733
- pair.a.size,
1734
- pair[aGutterSize]
1735
- );
1736
- Object.keys(style).forEach(function(prop) {
1737
- elements[pair.a].element.style[prop] = "";
1738
- elements[pair.b].element.style[prop] = "";
1739
- });
1740
- }
1741
- });
1742
- }
1743
- return {
1744
- setSizes,
1745
- getSizes,
1746
- collapse: function collapse(i) {
1747
- adjustToMin(elements[i]);
1748
- },
1749
- destroy,
1750
- parent,
1751
- pairs
1752
- };
1753
- };
1754
- split_es_default = Split;
1755
- }
1756
- });
1757
-
1758
- // node_modules/react-split/dist/react-split.es.js
1759
- function objectWithoutProperties(obj, exclude) {
1760
- var target = {};
1761
- for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k];
1762
- return target;
1763
- }
1764
- var import_react5, import_prop_types, SplitWrapper, react_split_es_default;
1765
- var init_react_split_es = __esm({
1766
- "node_modules/react-split/dist/react-split.es.js"() {
1767
- "use strict";
1768
- import_react5 = __toESM(require("react"));
1769
- import_prop_types = __toESM(require_prop_types());
1770
- init_split_es();
1771
- SplitWrapper = /* @__PURE__ */ (function(superclass) {
1772
- function SplitWrapper2() {
1773
- superclass.apply(this, arguments);
1774
- }
1775
- if (superclass) SplitWrapper2.__proto__ = superclass;
1776
- SplitWrapper2.prototype = Object.create(superclass && superclass.prototype);
1777
- SplitWrapper2.prototype.constructor = SplitWrapper2;
1778
- SplitWrapper2.prototype.componentDidMount = function componentDidMount() {
1779
- var ref = this.props;
1780
- ref.children;
1781
- var gutter = ref.gutter;
1782
- var rest = objectWithoutProperties(ref, ["children", "gutter"]);
1783
- var options = rest;
1784
- options.gutter = function(index, direction) {
1785
- var gutterElement;
1786
- if (gutter) {
1787
- gutterElement = gutter(index, direction);
1788
- } else {
1789
- gutterElement = document.createElement("div");
1790
- gutterElement.className = "gutter gutter-" + direction;
1791
- }
1792
- gutterElement.__isSplitGutter = true;
1793
- return gutterElement;
1794
- };
1795
- this.split = split_es_default(this.parent.children, options);
1796
- };
1797
- SplitWrapper2.prototype.componentDidUpdate = function componentDidUpdate(prevProps) {
1798
- var this$1 = this;
1799
- var ref = this.props;
1800
- ref.children;
1801
- var minSize = ref.minSize;
1802
- var sizes = ref.sizes;
1803
- var collapsed = ref.collapsed;
1804
- var rest = objectWithoutProperties(ref, ["children", "minSize", "sizes", "collapsed"]);
1805
- var options = rest;
1806
- var prevMinSize = prevProps.minSize;
1807
- var prevSizes = prevProps.sizes;
1808
- var prevCollapsed = prevProps.collapsed;
1809
- var otherProps = [
1810
- "maxSize",
1811
- "expandToMin",
1812
- "gutterSize",
1813
- "gutterAlign",
1814
- "snapOffset",
1815
- "dragInterval",
1816
- "direction",
1817
- "cursor"
1818
- ];
1819
- var needsRecreate = otherProps.map(function(prop) {
1820
- return this$1.props[prop] !== prevProps[prop];
1821
- }).reduce(function(accum, same) {
1822
- return accum || same;
1823
- }, false);
1824
- if (Array.isArray(minSize) && Array.isArray(prevMinSize)) {
1825
- var minSizeChanged = false;
1826
- minSize.forEach(function(minSizeI, i) {
1827
- minSizeChanged = minSizeChanged || minSizeI !== prevMinSize[i];
1828
- });
1829
- needsRecreate = needsRecreate || minSizeChanged;
1830
- } else if (Array.isArray(minSize) || Array.isArray(prevMinSize)) {
1831
- needsRecreate = true;
1832
- } else {
1833
- needsRecreate = needsRecreate || minSize !== prevMinSize;
1834
- }
1835
- if (needsRecreate) {
1836
- options.minSize = minSize;
1837
- options.sizes = sizes || this.split.getSizes();
1838
- this.split.destroy(true, true);
1839
- options.gutter = function(index, direction, pairB) {
1840
- return pairB.previousSibling;
1841
- };
1842
- this.split = split_es_default(
1843
- Array.from(this.parent.children).filter(
1844
- // eslint-disable-next-line no-underscore-dangle
1845
- function(element) {
1846
- return !element.__isSplitGutter;
1847
- }
1848
- ),
1849
- options
1850
- );
1851
- } else if (sizes) {
1852
- var sizeChanged = false;
1853
- sizes.forEach(function(sizeI, i) {
1854
- sizeChanged = sizeChanged || sizeI !== prevSizes[i];
1855
- });
1856
- if (sizeChanged) {
1857
- this.split.setSizes(this.props.sizes);
1858
- }
1859
- }
1860
- if (Number.isInteger(collapsed) && (collapsed !== prevCollapsed || needsRecreate)) {
1861
- this.split.collapse(collapsed);
1862
- }
1863
- };
1864
- SplitWrapper2.prototype.componentWillUnmount = function componentWillUnmount() {
1865
- this.split.destroy();
1866
- delete this.split;
1867
- };
1868
- SplitWrapper2.prototype.render = function render() {
1869
- var this$1 = this;
1870
- var ref = this.props;
1871
- ref.sizes;
1872
- ref.minSize;
1873
- ref.maxSize;
1874
- ref.expandToMin;
1875
- ref.gutterSize;
1876
- ref.gutterAlign;
1877
- ref.snapOffset;
1878
- ref.dragInterval;
1879
- ref.direction;
1880
- ref.cursor;
1881
- ref.gutter;
1882
- ref.elementStyle;
1883
- ref.gutterStyle;
1884
- ref.onDrag;
1885
- ref.onDragStart;
1886
- ref.onDragEnd;
1887
- ref.collapsed;
1888
- var children = ref.children;
1889
- var rest$1 = objectWithoutProperties(ref, ["sizes", "minSize", "maxSize", "expandToMin", "gutterSize", "gutterAlign", "snapOffset", "dragInterval", "direction", "cursor", "gutter", "elementStyle", "gutterStyle", "onDrag", "onDragStart", "onDragEnd", "collapsed", "children"]);
1890
- var rest = rest$1;
1891
- return import_react5.default.createElement(
1892
- "div",
1893
- Object.assign(
1894
- {},
1895
- { ref: function(parent) {
1896
- this$1.parent = parent;
1897
- } },
1898
- rest
1899
- ),
1900
- children
1901
- );
1902
- };
1903
- return SplitWrapper2;
1904
- })(import_react5.default.Component);
1905
- SplitWrapper.propTypes = {
1906
- sizes: import_prop_types.default.arrayOf(import_prop_types.default.number),
1907
- minSize: import_prop_types.default.oneOfType([
1908
- import_prop_types.default.number,
1909
- import_prop_types.default.arrayOf(import_prop_types.default.number)
1910
- ]),
1911
- maxSize: import_prop_types.default.oneOfType([
1912
- import_prop_types.default.number,
1913
- import_prop_types.default.arrayOf(import_prop_types.default.number)
1914
- ]),
1915
- expandToMin: import_prop_types.default.bool,
1916
- gutterSize: import_prop_types.default.number,
1917
- gutterAlign: import_prop_types.default.string,
1918
- snapOffset: import_prop_types.default.oneOfType([
1919
- import_prop_types.default.number,
1920
- import_prop_types.default.arrayOf(import_prop_types.default.number)
1921
- ]),
1922
- dragInterval: import_prop_types.default.number,
1923
- direction: import_prop_types.default.string,
1924
- cursor: import_prop_types.default.string,
1925
- gutter: import_prop_types.default.func,
1926
- elementStyle: import_prop_types.default.func,
1927
- gutterStyle: import_prop_types.default.func,
1928
- onDrag: import_prop_types.default.func,
1929
- onDragStart: import_prop_types.default.func,
1930
- onDragEnd: import_prop_types.default.func,
1931
- collapsed: import_prop_types.default.number,
1932
- children: import_prop_types.default.arrayOf(import_prop_types.default.element)
1933
- };
1934
- SplitWrapper.defaultProps = {
1935
- sizes: void 0,
1936
- minSize: void 0,
1937
- maxSize: void 0,
1938
- expandToMin: void 0,
1939
- gutterSize: void 0,
1940
- gutterAlign: void 0,
1941
- snapOffset: void 0,
1942
- dragInterval: void 0,
1943
- direction: void 0,
1944
- cursor: void 0,
1945
- gutter: void 0,
1946
- elementStyle: void 0,
1947
- gutterStyle: void 0,
1948
- onDrag: void 0,
1949
- onDragStart: void 0,
1950
- onDragEnd: void 0,
1951
- collapsed: void 0,
1952
- children: void 0
1953
- };
1954
- react_split_es_default = SplitWrapper;
1955
- }
1956
- });
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
-
1986
- // src/ai-plugin/jmx-ai/context.ts
1987
- function useMBeanTree() {
1988
- const [tree, setTree] = (0, import_react7.useState)(import_react6.MBeanTree.createEmpty(pluginName));
1989
- const [loaded, setLoaded] = (0, import_react7.useState)(false);
1990
- const { selectedNode, setSelectedNode } = (0, import_react7.useContext)(import_react6.PluginNodeSelectionContext);
1991
- const navigate = (0, import_react_router_dom.useNavigate)();
1992
- const [searchParams, setSearchParams] = (0, import_react_router_dom.useSearchParams)();
1993
- const refSelectedNode = (0, import_react7.useRef)();
1994
- refSelectedNode.current = selectedNode;
1995
- const populateTree = async () => {
1996
- const wkspTree = await import_react6.workspace.getTree();
1997
- setTree(wkspTree);
1998
- const nodeId = searchParams.get(PARAM_KEY_NODE_ID);
1999
- if (nodeId && nodeId !== refSelectedNode.current?.id) {
2000
- log.debug("Restore selected node with nid:", nodeId);
2001
- const urlNode = wkspTree.find((node) => node.id === nodeId);
2002
- if (urlNode) {
2003
- setSelectedNode(urlNode);
2004
- refSelectedNode.current = urlNode;
2005
- } else {
2006
- log.debug("Clear invalid nid:", nodeId);
2007
- searchParams.delete(PARAM_KEY_NODE_ID);
2008
- setSearchParams(searchParams);
2009
- }
2010
- }
2011
- if (!refSelectedNode.current) return;
2012
- const path = [...refSelectedNode.current.path()];
2013
- wkspTree.forEach(path, (node) => {
2014
- node.defaultExpanded = true;
2015
- });
2016
- const newSelected = wkspTree.navigate(...path);
2017
- if (newSelected) {
2018
- setSelectedNode(newSelected);
2019
- navigate(pluginPathWithNodeId(newSelected, searchParams));
2020
- } else {
2021
- navigate(pluginPath);
2022
- }
2023
- };
2024
- (0, import_react7.useEffect)(() => {
2025
- const loadTree = async () => {
2026
- await populateTree();
2027
- setLoaded(true);
2028
- };
2029
- const listener = () => {
2030
- setLoaded(false);
2031
- loadTree();
2032
- };
2033
- import_react6.eventService.onRefresh(listener);
2034
- loadTree();
2035
- return () => import_react6.eventService.removeListener(import_react6.EVENT_REFRESH, listener);
2036
- }, []);
2037
- return { tree, loaded, selectedNode, setSelectedNode };
2038
- }
2039
- function pluginPathWithNodeId(node, searchParams = new URLSearchParams(window.location.search)) {
2040
- searchParams.set(PARAM_KEY_NODE_ID, node.id);
2041
- const query = `?${searchParams.toString()}`;
2042
- return { pathname: pluginPath, search: query };
2043
- }
2044
- function useChatbot() {
2045
- const [messages, setMessages] = (0, import_react7.useState)([]);
2046
- const [dialogs, setDialogs] = (0, import_react7.useState)([]);
2047
- const [conversations, setConversations] = (0, import_react7.useState)([]);
2048
- const [announcement, setAnnouncement] = (0, import_react7.useState)("");
2049
- const [isChatbotOpen, setIsChatbotOpen] = (0, import_react7.useState)(false);
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
- };
2073
- return {
2074
- messages,
2075
- setMessages,
2076
- dialogs,
2077
- setDialogs,
2078
- conversations,
2079
- setConversations,
2080
- announcement,
2081
- setAnnouncement,
2082
- isChatbotOpen,
2083
- setIsChatbotOpen,
2084
- isSendButtonDisabled,
2085
- setIsSendButtonDisabled,
2086
- updateConversations
2087
- };
2088
- }
2089
- var import_react6, import_react7, import_react_router_dom, MBeanTreeContext, ChatbotContext;
2090
- var init_context = __esm({
2091
- "src/ai-plugin/jmx-ai/context.ts"() {
2092
- "use strict";
2093
- import_react6 = require("@hawtio/react");
2094
- import_react7 = require("react");
2095
- import_react_router_dom = require("react-router-dom");
2096
- init_globals();
2097
- init_model();
2098
- MBeanTreeContext = (0, import_react7.createContext)({
2099
- tree: import_react6.MBeanTree.createEmpty(pluginName),
2100
- loaded: false,
2101
- selectedNode: null,
2102
- setSelectedNode: () => {
2103
- }
2104
- });
2105
- ChatbotContext = (0, import_react7.createContext)({
2106
- messages: [],
2107
- setMessages: () => {
2108
- },
2109
- dialogs: [],
2110
- setDialogs: () => {
2111
- },
2112
- conversations: [],
2113
- setConversations: () => {
2114
- },
2115
- announcement: "",
2116
- setAnnouncement: () => {
2117
- },
2118
- isChatbotOpen: false,
2119
- setIsChatbotOpen: () => {
2120
- },
2121
- isSendButtonDisabled: false,
2122
- setIsSendButtonDisabled: () => {
2123
- },
2124
- updateConversations: () => {
2125
- }
2126
- });
2127
- }
2128
- });
2129
-
2130
- // src/ai-plugin/jmx-ai/Jmx.css
2131
- var init_Jmx = __esm({
2132
- "src/ai-plugin/jmx-ai/Jmx.css"() {
2133
- }
2134
- });
2135
-
2136
- // src/ai-plugin/jmx-ai/DiagnosisChatbot.tsx
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;
2138
- var init_DiagnosisChatbot = __esm({
2139
- "src/ai-plugin/jmx-ai/DiagnosisChatbot.tsx"() {
2140
- "use strict";
2141
- import_ui = require("@hawtio/react/ui");
2142
- import_chatbot = require("@patternfly/chatbot");
2143
- import_Chatbot = __toESM(require("@patternfly/chatbot/dist/dynamic/Chatbot"));
2144
- import_ChatbotContent = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotContent"));
2145
- import_ChatbotConversationHistoryNav = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav"));
2146
- import_ChatbotFooter = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotFooter"));
2147
- import_ChatbotHeader = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotHeader"));
2148
- import_Message = __toESM(require("@patternfly/chatbot/dist/dynamic/Message"));
2149
- import_MessageBar = __toESM(require("@patternfly/chatbot/dist/dynamic/MessageBar"));
2150
- import_MessageBox = __toESM(require("@patternfly/chatbot/dist/dynamic/MessageBox"));
2151
- import_react_core2 = require("@patternfly/react-core");
2152
- import_wrench_icon = __toESM(require("@patternfly/react-icons/dist/esm/icons/wrench-icon"));
2153
- import_react8 = __toESM(require("react"));
2154
- init_ai_service();
2155
- init_context();
2156
- init_globals();
2157
- import_jsx_runtime2 = require("react/jsx-runtime");
2158
- DiagnosisChatbot = () => {
2159
- const { setMessages, dialogs, conversations } = (0, import_react8.useContext)(ChatbotContext);
2160
- const [isDrawerOpen, setIsDrawerOpen] = (0, import_react8.useState)(false);
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);
2168
- }
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);
2178
- };
2179
- const displayMode = import_Chatbot.ChatbotDisplayMode.drawer;
2180
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Chatbot.default, { isCompact: true, displayMode, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2181
- import_ChatbotConversationHistoryNav.default,
2182
- {
2183
- isCompact: true,
2184
- drawerPanelContentProps: { isResizable: true, minSize: "200px" },
2185
- displayMode,
2186
- onDrawerToggle: () => {
2187
- setIsDrawerOpen(!isDrawerOpen);
2188
- setFilteredConversations(conversations);
2189
- },
2190
- isDrawerOpen,
2191
- setIsDrawerOpen,
2192
- onSelectActiveItem: (_e, selectedItem) => onSelectItemInHistory(String(selectedItem)),
2193
- conversations: [...filteredConversations].reverse(),
2194
- onNewChat: () => {
2195
- setIsDrawerOpen(!isDrawerOpen);
2196
- setFilteredConversations(conversations);
2197
- setMessages([]);
2198
- },
2199
- handleTextInputChange: handleSearchTextChange,
2200
- drawerContent: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2201
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DiagnosisChatbotHeader, { isDrawerOpen, setIsDrawerOpen }),
2202
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DiagnosisChatbotContent, {}),
2203
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(DiagnosisChatbotFooter, {})
2204
- ] })
2205
- }
2206
- ) });
2207
- };
2208
- DiagnosisChatbotHeader = ({ isDrawerOpen, setIsDrawerOpen }) => {
2209
- const { setIsChatbotOpen } = (0, import_react8.useContext)(ChatbotContext);
2210
- const modelName = aiService.getModel()?.name;
2211
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ChatbotHeader.default, { children: [
2212
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ChatbotHeader.ChatbotHeaderMain, { children: [
2213
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ChatbotHeader.ChatbotHeaderMenu, { "aria-expanded": isDrawerOpen, onMenuToggle: () => setIsDrawerOpen(!isDrawerOpen) }),
2214
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ChatbotHeader.ChatbotHeaderTitle, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Content, { component: "h2", children: "AI - Diagnosis" }) })
2215
- ] }),
2216
- /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ChatbotHeader.ChatbotHeaderActions, { children: [
2217
- modelName && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Label, { variant: "outline", children: modelName }),
2218
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ChatbotHeader.ChatbotHeaderCloseButton, { onClick: () => setIsChatbotOpen(false) })
2219
- ] })
2220
- ] });
2221
- };
2222
- DiagnosisChatbotContent = () => {
2223
- const { messages, announcement } = (0, import_react8.useContext)(ChatbotContext);
2224
- const scrollToBottomRef = (0, import_react8.useRef)(null);
2225
- (0, import_react8.useEffect)(() => {
2226
- if (messages.length > 2) {
2227
- scrollToBottomRef.current?.scrollIntoView({ behavior: "smooth" });
2228
- }
2229
- }, [messages]);
2230
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ChatbotContent.default, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_MessageBox.default, { announcement, children: messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react8.default.Fragment, { children: [
2231
- index === messages.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: scrollToBottomRef }),
2232
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_Message.default, { ...message }, message.id)
2233
- ] }, message.id)) }) });
769
+ import_react_core2 = require("@patternfly/react-core");
770
+ import_wrench_icon = __toESM(require("@patternfly/react-icons/dist/esm/icons/wrench-icon"));
771
+ import_jsx_runtime2 = require("react/jsx-runtime");
772
+ ToolCallsInfo = ({ call, index }) => {
773
+ 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, isInline: true, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("p", { children: [
774
+ "Args: ",
775
+ JSON.stringify(call.args)
776
+ ] }) }, index);
2234
777
  };
2235
- DiagnosisChatbotFooter = () => {
2236
- const { username } = (0, import_react8.useContext)(import_ui.PageContext);
2237
- const { messages, setAnnouncement, isSendButtonDisabled, setIsSendButtonDisabled, updateConversations } = (0, import_react8.useContext)(ChatbotContext);
2238
- const messagesRef = (0, import_react8.useRef)(messages);
2239
- (0, import_react8.useEffect)(() => {
778
+ }
779
+ });
780
+
781
+ // src/ai-plugin/chat/ToolCallsApprove.tsx
782
+ var import_ui, import_react_core3, import_react7, import_jsx_runtime3, ToolCallsApprove;
783
+ var init_ToolCallsApprove = __esm({
784
+ "src/ai-plugin/chat/ToolCallsApprove.tsx"() {
785
+ "use strict";
786
+ import_ui = require("@hawtio/react/ui");
787
+ import_react_core3 = require("@patternfly/react-core");
788
+ import_react7 = require("react");
789
+ init_ai_service();
790
+ init_context();
791
+ init_globals();
792
+ init_ThinkInfo();
793
+ init_ToolCallsInfo();
794
+ import_jsx_runtime3 = require("react/jsx-runtime");
795
+ ToolCallsApprove = ({ toolCalls, messageId }) => {
796
+ const { username } = (0, import_react7.useContext)(import_ui.PageContext);
797
+ const { messages, setAnnouncement, setIsSendButtonDisabled, updateConversations } = (0, import_react7.useContext)(ChatbotContext);
798
+ const messagesRef = (0, import_react7.useRef)(messages);
799
+ (0, import_react7.useEffect)(() => {
2240
800
  messagesRef.current = messages;
2241
801
  }, [messages]);
2242
- const handleSend = async (message) => {
2243
- if (!message.trim()) {
2244
- return;
2245
- }
2246
- log.debug("Send", messagesRef.current);
2247
- setIsSendButtonDisabled(true);
2248
- const newMessages = [];
2249
- newMessages.push(...messagesRef.current);
2250
- newMessages.push(aiService.createUserMessage(username, message));
2251
- newMessages.push(aiService.createLoadingBotMessage());
2252
- updateConversations(newMessages);
2253
- setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`);
2254
- log.debug("handleSend - new messages:", newMessages);
2255
- const dialogId = newMessages[0].id;
2256
- const answer = await (newMessages.length === 2 ? aiService.newChat(dialogId, message) : aiService.chat(dialogId, message));
2257
- const loadedMessages = [];
2258
- loadedMessages.push(...newMessages);
2259
- log.debug("handleSend - loaded messages:", loadedMessages);
2260
- loadedMessages.pop();
2261
- const botMessage = aiService.toBotMessage(answer, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
2262
- loadedMessages.push(botMessage);
2263
- updateConversations(loadedMessages);
2264
- setAnnouncement(`Message from Bot: ${answer}`);
2265
- setIsSendButtonDisabled(false);
802
+ const removeApproveButtons = (messages2) => {
803
+ return messages2.map(
804
+ (m) => m.id === messageId ? { ...m, extraContent: { ...m.extraContent, afterMainContent: void 0 } } : m
805
+ );
2266
806
  };
2267
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_ChatbotFooter.default, { children: [
2268
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2269
- import_MessageBar.default,
2270
- {
2271
- onSendMessage: (m) => handleSend(String(m)),
2272
- hasAttachButton: false,
2273
- isSendButtonDisabled
2274
- }
2275
- ),
2276
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_ChatbotFooter.ChatbotFootnote, { label: "AI may be inaccurate. Please verify important information." })
2277
- ] });
2278
- };
2279
- ThinkInfo = (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 }) });
2281
- };
2282
- ToolCallsInfo = (call, index) => {
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: [
2284
- "Args: ",
2285
- JSON.stringify(call.args),
2286
- " "
2287
- ] }) }, index);
2288
- };
2289
- ToolCallsApprove = (toolCalls) => {
2290
- const { username } = (0, import_react8.useContext)(import_ui.PageContext);
2291
- const { messages, setAnnouncement, setIsSendButtonDisabled, updateConversations } = (0, import_react8.useContext)(ChatbotContext);
2292
- const messagesRef = (0, import_react8.useRef)(messages);
2293
807
  const approve = async (toolCalls2) => {
2294
- log.debug("Approved", messagesRef.current);
808
+ log.debug("ToolCallsApprove - Approved", messagesRef.current);
2295
809
  setIsSendButtonDisabled(true);
2296
- const newMessages = [];
2297
- newMessages.push(...messagesRef.current);
810
+ const newMessages = removeApproveButtons([...messagesRef.current]);
2298
811
  newMessages.push(aiService.createUserMessage(username, "Approved"));
2299
812
  newMessages.push(aiService.createLoadingBotMessage());
2300
813
  updateConversations(newMessages);
2301
814
  setAnnouncement(`User approved tool usage. Message from Bot is loading.`);
2302
- log.debug("approve - newMessages:", newMessages);
2303
815
  const dialogId = newMessages[0].id;
2304
- const answer = await aiService.invokeTools(dialogId, toolCalls2);
2305
- log.debug("Answer:", answer);
2306
- const loadedMessages = [];
2307
- loadedMessages.push(...newMessages);
2308
- log.debug("approve - loadedMessages:", loadedMessages);
816
+ const loadedMessages = [...newMessages];
817
+ const answer = await aiService.invokeTools(dialogId, toolCalls2, (intermediateAnswer) => {
818
+ loadedMessages.pop();
819
+ loadedMessages.push(aiService.toBotMessage(intermediateAnswer, true, ThinkInfo, ToolCallsInfo, ToolCallsApprove));
820
+ loadedMessages.push(aiService.createLoadingBotMessage());
821
+ updateConversations([...loadedMessages]);
822
+ });
2309
823
  loadedMessages.pop();
2310
- const botMessage = aiService.toBotMessage(answer, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
824
+ const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
2311
825
  loadedMessages.push(botMessage);
2312
- updateConversations(loadedMessages);
826
+ updateConversations([...loadedMessages]);
2313
827
  setAnnouncement(`Message from Bot: ${answer}`);
2314
- setIsSendButtonDisabled(false);
828
+ if (!aiService.hasToolCalls(answer)) {
829
+ setIsSendButtonDisabled(false);
830
+ }
2315
831
  };
2316
832
  const reject = () => {
2317
- log.debug("Rejected");
2318
- setIsSendButtonDisabled(true);
2319
- const newMessages = [];
2320
- newMessages.push(...messages);
833
+ log.debug("ToolCallsApprove - Rejected", messagesRef.current);
834
+ const currentMessages = messagesRef.current;
835
+ const dialogId = currentMessages[0]?.id;
836
+ if (dialogId) {
837
+ aiService.rejectTools(dialogId, toolCalls);
838
+ }
839
+ const newMessages = removeApproveButtons([...currentMessages]);
2321
840
  newMessages.push(aiService.createUserMessage(username, "Rejected"));
2322
841
  updateConversations(newMessages);
2323
842
  setIsSendButtonDisabled(false);
2324
843
  };
2325
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react_core2.Flex, { columnGap: { default: "columnGapSm" }, children: [
2326
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Button, { variant: "primary", onClick: () => approve(toolCalls), children: "Approve" }),
2327
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_core2.Button, { variant: "secondary", onClick: reject, children: "Reject" })
844
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_core3.Flex, { columnGap: { default: "columnGapSm" }, children: [
845
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.Button, { variant: "primary", onClick: () => approve(toolCalls), children: "Approve" }),
846
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_core3.Button, { variant: "secondary", onClick: reject, children: "Reject" })
2328
847
  ] });
2329
848
  };
2330
849
  }
2331
850
  });
2332
851
 
2333
- // src/ai-plugin/jmx-ai/JmxContent.css
2334
- var init_JmxContent = __esm({
2335
- "src/ai-plugin/jmx-ai/JmxContent.css"() {
2336
- }
2337
- });
2338
-
2339
- // node_modules/jolokia.js/dist/jolokia.mjs
2340
- function prepareRequest(request, agentOptions, params) {
2341
- const opts = Object.assign({}, agentOptions, { dataType: "json" }, params);
2342
- assertNotNull(opts.url, "No URL given");
2343
- const fetchOptions = Object.assign({}, DEFAULT_FETCH_PARAMS);
2344
- fetchOptions.headers = {};
2345
- const method = extractMethod(request, opts);
2346
- let url = ensureTrailingSlash(opts.url);
2347
- if (opts.headers) {
2348
- Object.assign(fetchOptions.headers, opts.headers);
2349
- }
2350
- if (method === "post") {
2351
- fetchOptions.method = "POST";
2352
- Object.assign(fetchOptions.headers, { "Content-Type": "text/json" });
2353
- } else {
2354
- fetchOptions.method = "GET";
2355
- url += constructGetUrlPath(request);
2356
- }
2357
- url = addProcessingParameters(url, opts);
2358
- if (opts.username && opts.password) {
2359
- if (typeof window.btoa === "function") {
2360
- fetchOptions.headers["Authorization"] = "Basic " + window.btoa(opts.username + ":" + opts.password);
2361
- } else {
2362
- console.warn(`Can't set "Authorization" header - no btoa() function available`);
2363
- }
2364
- }
2365
- if (opts.timeout != null) {
2366
- fetchOptions.signal = AbortSignal.timeout(opts.timeout);
2367
- }
2368
- let successCb = void 0;
2369
- let errorCb = void 0;
2370
- let fetchErrorCb = void 0;
2371
- if ("success" in opts) {
2372
- successCb = constructCallbackDispatcher(opts.success);
2373
- errorCb = constructCallbackDispatcher(opts.error);
2374
- }
2375
- if ("error" in opts && !opts.success) {
2376
- successCb = constructCallbackDispatcher("ignore");
2377
- errorCb = constructCallbackDispatcher(opts.error);
2378
- }
2379
- if (!("fetchError" in opts)) {
2380
- if (successCb && errorCb) {
2381
- fetchErrorCb = (_response, reason) => {
2382
- console.warn(reason);
2383
- };
2384
- }
2385
- } else if (opts.fetchError === "ignore") {
2386
- fetchErrorCb = (_response, _reason) => {
2387
- };
2388
- } else {
2389
- fetchErrorCb = opts.fetchError;
2390
- }
2391
- return { url, fetchOptions, dataType: opts.dataType, resolve: opts.resolve, successCb, errorCb, fetchErrorCb };
2392
- }
2393
- async function performRequest(args) {
2394
- const { url, fetchOptions, dataType, resolve, successCb, errorCb, fetchErrorCb } = args;
2395
- if (successCb && errorCb) {
2396
- return fetch(url, fetchOptions).then(async (response) => {
2397
- if (response.status != 200) {
2398
- fetchErrorCb?.(response, response.statusText);
2399
- return void 0;
2400
- }
2401
- const ct = response.headers.get("content-type");
2402
- if (dataType === "text" || !ct || !(ct.startsWith("text/json") || ct.startsWith("application/json"))) {
2403
- const textResponse = await response.text();
2404
- void successCb(textResponse);
2405
- } else {
2406
- const jsonResponse = await response.json();
2407
- const responses = Array.isArray(jsonResponse) ? jsonResponse : [jsonResponse];
2408
- for (let n = 0; n < responses.length; n++) {
2409
- const resp = responses[n];
2410
- if (Jolokia.isError(resp)) {
2411
- errorCb(resp, n);
2412
- } else {
2413
- successCb(resp, n);
2414
- }
2415
- }
2416
- }
2417
- }).catch((reason) => {
2418
- fetchErrorCb?.(null, reason);
2419
- return void 0;
2420
- });
2421
- } else {
2422
- if (resolve === "response") {
2423
- return fetch(url, fetchOptions);
2424
- } else {
2425
- const promise = fetch(url, fetchOptions).then(async (response) => {
2426
- if (response.status != 200) {
2427
- throw response;
2428
- }
2429
- const ct = response.headers.get("content-type");
2430
- if (dataType === "text" || !ct || !(ct.startsWith("text/json") || ct.startsWith("application/json"))) {
2431
- return response.text();
2432
- }
2433
- return response.json();
2434
- });
2435
- if (fetchErrorCb) {
2436
- return promise.catch((error) => {
2437
- if (error instanceof Response) {
2438
- fetchErrorCb(error, null);
2439
- } else {
2440
- fetchErrorCb(null, error);
2441
- }
2442
- return void 0;
2443
- });
2444
- } else {
2445
- return promise;
2446
- }
2447
- }
2448
- }
2449
- }
2450
- function constructCallbackDispatcher(cb) {
2451
- if (!cb || Array.isArray(cb) && cb.length == 0) {
2452
- return (response, index) => {
2453
- let r;
2454
- if (typeof response === "string") {
2455
- r = response;
2456
- } else {
2457
- r = JSON.stringify(response);
2458
- }
2459
- if (r && r.length > 256) {
2460
- r = r.substring(0, 253) + "...";
2461
- }
2462
- console.warn("Ignore response", '"' + r + '"', "index=", index);
2463
- };
2464
- }
2465
- if (cb === "ignore") {
2466
- return () => {
2467
- };
2468
- }
2469
- const cbArray = Array.isArray(cb) ? cb : [cb];
2470
- return (response, index) => {
2471
- if (typeof response === "string") {
2472
- cbArray[0](response);
2473
- } else {
2474
- cbArray[index % cbArray.length](response, index);
2475
- }
2476
- };
2477
- }
2478
- function createJolokiaInvocation(jobs, agentOptions) {
2479
- const requestArguments = prepareRequest([], agentOptions, { method: "post" });
2480
- return function() {
2481
- const successCbs = [];
2482
- const errorCbs = [];
2483
- const requests = [];
2484
- const indexMapping = [];
2485
- const fetchErrorCbs = [];
2486
- for (const [jobId, job] of jobs) {
2487
- const reqsLen = job.requests.length;
2488
- if (job.success) {
2489
- const successCb = constructSuccessJobCallback(job, jobId, indexMapping);
2490
- const errorCb = constructErrorJobCallback(job, jobId, indexMapping);
2491
- for (let idx = 0; idx < reqsLen; idx++) {
2492
- requests.push(prepareJobRequest(job, idx));
2493
- successCbs.push(successCb);
2494
- errorCbs.push(errorCb);
2495
- indexMapping.push(idx);
2496
- }
2497
- if (job.fetchError) {
2498
- fetchErrorCbs.push(job.fetchError);
2499
- }
2500
- } else if (job.callback) {
2501
- const callbackConfiguration = constructJobCallbackConfiguration(job, jobId);
2502
- for (let idx = 0; idx < reqsLen - 1; idx++) {
2503
- requests.push(prepareJobRequest(job, idx));
2504
- successCbs.push(callbackConfiguration.cb);
2505
- errorCbs.push(callbackConfiguration.cb);
2506
- indexMapping.push(-1);
2507
- }
2508
- requests.push(prepareJobRequest(job, reqsLen - 1));
2509
- successCbs.push(callbackConfiguration.lcb);
2510
- errorCbs.push(callbackConfiguration.lcb);
2511
- indexMapping.push(-1);
2512
- const cb = (response, error) => {
2513
- job.callback(response ?? error);
2514
- };
2515
- fetchErrorCbs.push(cb);
2516
- }
2517
- }
2518
- if (requests.length > 0) {
2519
- requestArguments.fetchOptions.body = JSON.stringify(requests);
2520
- requestArguments.successCb = function(response, index) {
2521
- successCbs[index](response, index);
2522
- };
2523
- requestArguments.errorCb = function(response, index) {
2524
- errorCbs[index](response, index);
2525
- };
2526
- requestArguments.fetchErrorCb = function(response, error) {
2527
- if (fetchErrorCbs.length > 0) {
2528
- fetchErrorCbs.forEach((cb) => {
2529
- cb(response, error);
2530
- });
2531
- } else {
2532
- if (response) {
2533
- console.error("Problem executing registered jobs: ", response.status, response.statusText);
2534
- } else {
2535
- console.error("Problem executing registered jobs: ", error);
2536
- }
2537
- }
2538
- };
2539
- performRequest(requestArguments).catch((e) => {
2540
- console.warn("Problem invoking a poller", e);
2541
- });
2542
- }
2543
- };
2544
- }
2545
- function constructSuccessJobCallback(job, jobId, indexMapping) {
2546
- if (!job.success) {
2547
- throw "Expected 'success' callback configured for the job with ID=" + jobId;
2548
- }
2549
- return function(response, index) {
2550
- if (job.onlyIfModified) {
2551
- job.lastModified = response.timestamp;
2552
- }
2553
- job.success(response, jobId, indexMapping[index]);
2554
- };
2555
- }
2556
- function constructErrorJobCallback(job, jobId, indexMapping) {
2557
- if (!job.error) {
2558
- throw "Expected 'error' callback configured for the job with ID=" + jobId;
2559
- }
2560
- return function(response, index) {
2561
- if (response.status === 304) {
2562
- return;
2563
- } else {
2564
- job.error(response, jobId, indexMapping[index]);
2565
- }
2566
- };
2567
- }
2568
- function constructJobCallbackConfiguration(job, jobId) {
2569
- if (!job.callback) {
2570
- throw "Expected 'callback' configured for the job with ID=" + jobId;
2571
- }
2572
- const allResponses = [];
2573
- let lastModified = 0;
2574
- return {
2575
- cb: addResponse,
2576
- lcb: function(response, index) {
2577
- addResponse(response);
2578
- if (allResponses.length > 0) {
2579
- job.lastModified = lastModified;
2580
- job.callback(...allResponses);
2581
- }
2582
- }
2583
- };
2584
- function addResponse(response, _index) {
2585
- if (response.status !== 304) {
2586
- if (lastModified === 0 || response.timestamp && response.timestamp < lastModified) {
2587
- if (response.timestamp) {
2588
- lastModified = response.timestamp;
2589
- }
2590
- }
2591
- allResponses.push(response);
2592
- }
2593
- }
2594
- }
2595
- function prepareJobRequest(job, requestIndex) {
2596
- const request = job.requests[requestIndex];
2597
- const config = job.config || {};
2598
- const extraConfig = job.onlyIfModified && job.lastModified ? { ifModifiedSince: job.lastModified } : {};
2599
- request.config = Object.assign({}, config, request.config, extraConfig);
2600
- return request;
2601
- }
2602
- function assertNotNull(value, message) {
2603
- if (value == null) {
2604
- throw new Error(message);
2605
- }
2606
- }
2607
- function extractMethod(request, params) {
2608
- const methodGiven = params?.method?.toLowerCase();
2609
- let method;
2610
- if (!request) {
2611
- return "get";
2612
- }
2613
- if (methodGiven) {
2614
- if (methodGiven === "get") {
2615
- if (Array.isArray(request)) {
2616
- throw new Error("Cannot use GET with bulk requests");
2617
- }
2618
- if (request.type?.toLowerCase() === "read" && "attribute" in request && Array.isArray(request.attribute)) {
2619
- throw new Error("Cannot use GET for read with multiple attributes");
2620
- }
2621
- if ("target" in request) {
2622
- throw new Error("Cannot use GET request with proxy mode");
2623
- }
2624
- if ("config" in request) {
2625
- throw new Error("Cannot use GET with request specific config");
2626
- }
2627
- method = "get";
2628
- } else if (methodGiven !== "post") {
2629
- throw new Error('Illegal method "' + methodGiven + '"');
2630
- } else {
2631
- method = "post";
2632
- }
2633
- } else {
2634
- if (Array.isArray(request) || "config" in request || request.type?.toLowerCase() === "read" && "attribute" in request && Array.isArray(request.attribute) || "target" in request) {
2635
- method = "post";
2636
- } else {
2637
- method = "get";
2638
- }
2639
- }
2640
- return method;
2641
- }
2642
- function ensureTrailingSlash(url) {
2643
- const v = typeof url === "string" ? url : url.href;
2644
- let trimEnd = v.length;
2645
- while (v[trimEnd - 1] === "/") {
2646
- trimEnd--;
2647
- }
2648
- return v.substring(0, trimEnd) + "/";
2649
- }
2650
- function addProcessingParameters(url, opts) {
2651
- let sep = url.indexOf("?") > 0 ? "&" : "?";
2652
- PROCESSING_PARAMS.forEach(function(key) {
2653
- const v = opts[key];
2654
- if (v != null) {
2655
- url += sep + key + "=" + v;
2656
- sep = "&";
2657
- }
2658
- });
2659
- return url;
2660
- }
2661
- function valueToString(value) {
2662
- if (value == null) {
2663
- return "[null]";
2664
- }
2665
- if (Array.isArray(value)) {
2666
- let ret = "";
2667
- for (let i = 0; i < value.length; i++) {
2668
- const v = value[i];
2669
- ret += v == null ? "[null]" : singleValueToString(value[i]);
2670
- if (i < value.length - 1) {
2671
- ret += ",";
2672
- }
2673
- }
2674
- return ret;
2675
- } else {
2676
- return singleValueToString(value);
2677
- }
2678
- }
2679
- function singleValueToString(value) {
2680
- if (typeof value === "string" && value.length === 0) {
2681
- return '""';
2682
- } else {
2683
- return value.toString();
2684
- }
2685
- }
2686
- function constructGetUrlPath(request) {
2687
- let type = request.type;
2688
- assertNotNull(type, "No request type given for building a GET request");
2689
- type = type.toLowerCase();
2690
- const extractor = GET_URL_EXTRACTORS[type];
2691
- assertNotNull(extractor, "Unknown request type " + type);
2692
- const result = extractor(request);
2693
- const parts = result.parts || [];
2694
- let url = type;
2695
- parts.forEach(function(v) {
2696
- url += "/" + Jolokia.escape(v);
2697
- });
2698
- if (result.path) {
2699
- url += (result.path[0] === "/" ? "" : "/") + result.path;
2700
- }
2701
- return url;
2702
- }
2703
- function extractNotificationMode(client, opts) {
2704
- const backends = client.backend || {};
2705
- let mode = opts.mode;
2706
- if (!mode) {
2707
- mode = backends["sse"] ? "sse" : backends["pull"] ? "pull" : void 0;
2708
- if (!mode && backends.length === 1) {
2709
- return Object.keys(backends)[0];
2710
- }
2711
- }
2712
- if (!mode || !backends[mode]) {
2713
- throw new Error("Notification mode must be one of [" + Object.keys(backends) + "]" + (mode ? ', and not "' + mode + '"' : ""));
2714
- }
2715
- return mode;
2716
- }
2717
- var CLIENT_VERSION, DEFAULT_FETCH_PARAMS, PROCESSING_PARAMS, Jolokia, GET_URL_EXTRACTORS;
2718
- var init_jolokia = __esm({
2719
- "node_modules/jolokia.js/dist/jolokia.mjs"() {
852
+ // src/ai-plugin/chat/ChatbotPanel.tsx
853
+ var import_ui2, import_Chatbot, import_ChatbotContent, import_ChatbotConversationHistoryNav, import_ChatbotFooter, import_ChatbotHeader, import_ChatbotWelcomePrompt, import_Message, import_MessageBar, import_MessageBox, import_react_core4, import_react8, import_jsx_runtime4, ChatbotPanel, ChatbotPanelHeader, ChatbotPanelContent, ChatbotPanelFooter;
854
+ var init_ChatbotPanel = __esm({
855
+ "src/ai-plugin/chat/ChatbotPanel.tsx"() {
2720
856
  "use strict";
2721
- CLIENT_VERSION = "2.6.0";
2722
- DEFAULT_FETCH_PARAMS = {
2723
- cache: "no-store",
2724
- credentials: "same-origin",
2725
- redirect: "error"
2726
- };
2727
- PROCESSING_PARAMS = [
2728
- "maxDepth",
2729
- "maxCollectionSize",
2730
- "maxObjects",
2731
- "serializeLong",
2732
- "ignoreErrors",
2733
- "includeStackTrace",
2734
- "serializeException",
2735
- "canonicalNaming",
2736
- "mimeType",
2737
- "includeRequest",
2738
- "ifModifiedSince",
2739
- "listCache"
2740
- ];
2741
- Jolokia = function(config) {
2742
- if (!new.target) {
2743
- return new Jolokia(config);
2744
- }
2745
- const jobs = /* @__PURE__ */ new Map();
2746
- let jobId = 1;
2747
- let client;
2748
- const agentOptions = {};
2749
- let pollerIsRunning = false;
2750
- let timerId = null;
2751
- if (typeof config === "string") {
2752
- config = { url: config };
2753
- }
2754
- Object.assign(agentOptions, DEFAULT_FETCH_PARAMS, config);
2755
- this.request = async function(request, params) {
2756
- const args = prepareRequest(request, agentOptions, params);
2757
- if (args.fetchOptions.method === "POST") {
2758
- args.fetchOptions.body = JSON.stringify(request);
2759
- }
2760
- return performRequest(args);
2761
- };
2762
- this.register = function(jobInfo, ...requests) {
2763
- if (!requests || requests.length == 0) {
2764
- throw "At a least one request must be provided";
2765
- }
2766
- const job = { requests };
2767
- if (typeof jobInfo === "function") {
2768
- job.callback = jobInfo;
2769
- } else {
2770
- if ("callback" in jobInfo) {
2771
- job.callback = jobInfo.callback;
2772
- } else if ("success" in jobInfo && "error" in jobInfo) {
2773
- job.success = jobInfo.success;
2774
- job.error = jobInfo.error;
2775
- job.fetchError = jobInfo.fetchError;
2776
- } else {
2777
- throw "Either 'callback' or ('success' and 'error') callback must be provided when registering a Jolokia job";
2778
- }
2779
- job.config = jobInfo.config;
2780
- job.onlyIfModified = jobInfo.onlyIfModified;
2781
- }
2782
- return addJob(job);
2783
- };
2784
- this.unregister = function(handle) {
2785
- jobs.delete(handle);
2786
- };
2787
- this.jobs = function() {
2788
- return [...jobs.keys()];
2789
- };
2790
- this.start = function(interval) {
2791
- interval = interval || agentOptions.fetchInterval || 3e4;
2792
- if (pollerIsRunning) {
2793
- if (interval === agentOptions.fetchInterval) {
2794
- return;
2795
- }
2796
- this.stop();
857
+ import_ui2 = require("@hawtio/react/ui");
858
+ import_Chatbot = __toESM(require("@patternfly/chatbot/dist/dynamic/Chatbot"));
859
+ import_ChatbotContent = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotContent"));
860
+ import_ChatbotConversationHistoryNav = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav"));
861
+ import_ChatbotFooter = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotFooter"));
862
+ import_ChatbotHeader = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotHeader"));
863
+ import_ChatbotWelcomePrompt = __toESM(require("@patternfly/chatbot/dist/dynamic/ChatbotWelcomePrompt"));
864
+ import_Message = __toESM(require("@patternfly/chatbot/dist/dynamic/Message"));
865
+ import_MessageBar = __toESM(require("@patternfly/chatbot/dist/dynamic/MessageBar"));
866
+ import_MessageBox = __toESM(require("@patternfly/chatbot/dist/dynamic/MessageBox"));
867
+ import_react_core4 = require("@patternfly/react-core");
868
+ import_react8 = __toESM(require("react"));
869
+ init_ai_service();
870
+ init_context();
871
+ init_globals();
872
+ init_ThinkInfo();
873
+ init_ToolCallsApprove();
874
+ init_ToolCallsInfo();
875
+ import_jsx_runtime4 = require("react/jsx-runtime");
876
+ ChatbotPanel = ({ title, displayMode }) => {
877
+ const { setMessages, dialogs, conversations } = (0, import_react8.useContext)(ChatbotContext);
878
+ const [isDrawerOpen, setIsDrawerOpen] = (0, import_react8.useState)(false);
879
+ const [filteredConversations, setFilteredConversations] = (0, import_react8.useState)(conversations);
880
+ const onSelectItemInHistory = (selected) => {
881
+ log.debug("Selected conversation with ID:", selected);
882
+ const dialog = dialogs.find((c) => c.id === selected);
883
+ if (dialog) {
884
+ setMessages(dialog.messages);
885
+ setIsDrawerOpen(false);
2797
886
  }
2798
- agentOptions.fetchInterval = interval;
2799
- timerId = setInterval(createJolokiaInvocation(jobs, agentOptions), interval);
2800
- pollerIsRunning = true;
2801
887
  };
2802
- this.stop = function() {
2803
- if (!pollerIsRunning || !timerId) {
888
+ const handleSearchTextChange = (value) => {
889
+ if (value.trim() === "") {
890
+ setFilteredConversations(conversations);
2804
891
  return;
2805
892
  }
2806
- clearInterval(timerId);
2807
- timerId = null;
2808
- pollerIsRunning = false;
2809
- };
2810
- this.isRunning = function() {
2811
- return pollerIsRunning;
2812
- };
2813
- this.addNotificationListener = async function(opts) {
2814
- await ensureNotificationRegistration(this);
2815
- const mode = extractNotificationMode(client, opts);
2816
- notificationHandlerFunc("lazy-init", mode)();
2817
- return await this.request({
2818
- type: "notification",
2819
- command: "add",
2820
- mode,
2821
- client: client.id,
2822
- mbean: opts.mbean,
2823
- filter: opts.filter,
2824
- config: opts.config,
2825
- handback: opts.handback
2826
- }, { method: "post" }).then((responses) => {
2827
- const resp = responses;
2828
- if (Jolokia.isError(resp)) {
2829
- throw new Error("Cannot not add notification subscription for " + opts.mbean + " (client: " + client.id + "): " + resp.error);
2830
- }
2831
- const handle = {
2832
- id: resp.value,
2833
- mode
2834
- };
2835
- notificationHandlerFunc("add", mode)(this, handle, opts);
2836
- return handle;
2837
- });
2838
- };
2839
- this.removeNotificationListener = async function(handle) {
2840
- notificationHandlerFunc("remove", handle.mode)(this, handle);
2841
- return await this.request({
2842
- type: "notification",
2843
- command: "remove",
2844
- client: client.id,
2845
- handle: handle.id
2846
- }, { method: "post" }).then((responses) => {
2847
- const resp = responses;
2848
- return !Jolokia.isError(resp);
2849
- });
2850
- };
2851
- this.unregisterNotificationClient = async function() {
2852
- const backends = client.backend || {};
2853
- for (const mode in NOTIFICATION_HANDLERS) {
2854
- if (NOTIFICATION_HANDLERS[mode] && backends[mode]) {
2855
- notificationHandlerFunc("unregister", mode)();
2856
- }
2857
- }
2858
- return await this.request({
2859
- type: "notification",
2860
- command: "unregister",
2861
- client: client.id
2862
- }, { method: "post" }).then((responses) => {
2863
- const resp = responses;
2864
- return !Jolokia.isError(resp);
2865
- });
893
+ const filtered = conversations.filter((c) => c.text.toLowerCase().includes(value.toLowerCase()));
894
+ log.debug("Filtered conversations:", filtered);
895
+ setFilteredConversations(filtered);
2866
896
  };
2867
- function addJob(job) {
2868
- const id = jobId++;
2869
- jobs.set(id, job);
2870
- setTimeout(() => {
2871
- const newJobMap = /* @__PURE__ */ new Map();
2872
- newJobMap.set(id, job);
2873
- const jobFunction = createJolokiaInvocation(newJobMap, agentOptions);
2874
- jobFunction();
2875
- }, 0);
2876
- return id;
2877
- }
2878
- async function ensureNotificationRegistration(jolokia) {
2879
- if (!client) {
2880
- return jolokia.request({
2881
- type: "notification",
2882
- command: "register"
2883
- }, { method: "post" }).then((responses) => {
2884
- const resp = responses;
2885
- if (Jolokia.isError(resp)) {
2886
- throw new Error("Can not register client for notifications: " + resp.error + "\nTrace:\n" + resp.stacktrace);
2887
- } else {
2888
- client = resp.value;
2889
- }
2890
- return true;
2891
- });
2892
- } else {
2893
- return Promise.resolve(true);
2894
- }
2895
- }
2896
- function notificationHandlerFunc(what, mode) {
2897
- const notifHandler = NOTIFICATION_HANDLERS[mode];
2898
- if (!notifHandler) {
2899
- throw new Error("Unsupported notification mode '" + mode + "'");
2900
- }
2901
- return function(jolokia, handle, opts) {
2902
- return notifHandler[what]?.apply(notifHandler, [jolokia, handle, opts]);
2903
- };
2904
- }
2905
- const NOTIFICATION_HANDLERS = {
2906
- "pull": {
2907
- // "pull" handler is based on server-side MBean instance collecting notifications for all registered
2908
- // clients. In order to get the notifications, we have to call this MBean's "pull" operation, passing
2909
- // client ID and handle ID
2910
- // --- operations of pull notification mechanism
2911
- add: function(_jolokia, handle, opts) {
2912
- const job = {
2913
- callback: function(resp) {
2914
- if (!Jolokia.isResponseFetchError(resp) && !Jolokia.isError(resp)) {
2915
- const notifs = resp.value;
2916
- if (notifs && notifs.notifications && notifs.notifications.length > 0) {
2917
- opts?.callback?.(notifs);
2918
- }
2919
- }
2920
- },
2921
- requests: [{
2922
- type: "exec",
2923
- mbean: client.backend["pull"].store,
2924
- operation: "pull",
2925
- arguments: [client.id, handle.id]
2926
- }]
2927
- };
2928
- this.jobIds[handle.id] = addJob(job);
897
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Chatbot.default, { isCompact: true, displayMode, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
898
+ import_ChatbotConversationHistoryNav.default,
899
+ {
900
+ isCompact: true,
901
+ drawerPanelContentProps: { isResizable: true, minSize: "200px" },
902
+ displayMode,
903
+ onDrawerToggle: () => {
904
+ setIsDrawerOpen(!isDrawerOpen);
905
+ setFilteredConversations(conversations);
2929
906
  },
2930
- remove: function(jolokia, handle) {
2931
- const job = this.jobIds[handle.id];
2932
- if (job != void 0) {
2933
- jolokia.unregister(job);
2934
- delete this.jobIds[handle.id];
2935
- }
907
+ isDrawerOpen,
908
+ setIsDrawerOpen,
909
+ onSelectActiveItem: (_e, selectedItem) => onSelectItemInHistory(String(selectedItem)),
910
+ conversations: [...filteredConversations].reverse(),
911
+ onNewChat: () => {
912
+ setIsDrawerOpen(false);
913
+ setFilteredConversations(conversations);
914
+ setMessages([]);
2936
915
  },
2937
- unregister: function(jolokia) {
2938
- for (const handleId in this.jobIds) {
2939
- if (this.jobIds[handleId] != void 0) {
2940
- jolokia.unregister(this.jobIds[handleId]);
916
+ handleTextInputChange: handleSearchTextChange,
917
+ drawerContent: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
918
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
919
+ ChatbotPanelHeader,
920
+ {
921
+ isDrawerOpen,
922
+ setIsDrawerOpen,
923
+ title,
924
+ hasCloseButton: displayMode === import_Chatbot.ChatbotDisplayMode.drawer
2941
925
  }
2942
- }
2943
- this.jobIds = {};
2944
- },
2945
- // --- state of pull notification mechanism
2946
- jobIds: {}
2947
- },
2948
- "sse": {
2949
- // "sse" handler is based on https://developer.mozilla.org/en-US/docs/Web/API/EventSource
2950
- // and continuous stream of events sent over single HTTP connection with text/event-stream MIME type
2951
- // the messages sent are JSON representations of org.jolokia.server.core.service.notification.NotificationResult instances
2952
- // --- operations of sse notification mechanism
2953
- "lazy-init": function() {
2954
- if (!this.eventSource) {
2955
- this.eventSource = new EventSource(agentOptions.url + "/notification/open/" + client.id + "/sse");
2956
- const dispatchers = this.dispatchMap;
2957
- this.eventSource.addEventListener("message", function(event) {
2958
- const data = JSON.parse(event.data);
2959
- if (data.handle) {
2960
- const callback = dispatchers[data.handle];
2961
- callback?.(data);
2962
- }
2963
- });
2964
- }
2965
- },
2966
- add: function(_jolokia, handle, opts) {
2967
- this.dispatchMap[handle.id] = opts.callback;
2968
- },
2969
- remove: function(_jolokia, handle) {
2970
- delete this.dispatchMap[handle.id];
2971
- },
2972
- unregister: function() {
2973
- this.dispatchMap = {};
2974
- this.eventSource?.close();
2975
- this.eventSource = null;
2976
- },
2977
- // --- state of sse notification mechanism
2978
- // Map for dispatching SSE return notifications
2979
- dispatchMap: {},
2980
- // SSE event-source
2981
- eventSource: null
926
+ ),
927
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatbotPanelContent, {}),
928
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ChatbotPanelFooter, {})
929
+ ] })
2982
930
  }
2983
- };
2984
- };
2985
- Object.defineProperty(Jolokia.prototype, "CLIENT_VERSION", {
2986
- value: CLIENT_VERSION,
2987
- enumerable: true,
2988
- writable: false
2989
- });
2990
- Jolokia.escape = Jolokia.prototype.escape = function(part) {
2991
- return encodeURIComponent(part.replace(/!/g, "!!").replace(/\//g, "!/"));
2992
- };
2993
- Jolokia.escapePost = Jolokia.prototype.escape = function(part) {
2994
- return part.replace(/!/g, "!!").replace(/\//g, "!/");
2995
- };
2996
- Jolokia.isError = Jolokia.prototype.isError = function(resp) {
2997
- return resp == null || resp.status != 200;
2998
- };
2999
- Jolokia.isResponseSuccess = function(resp) {
3000
- if (!resp || typeof resp !== "object")
3001
- return false;
3002
- return "status" in resp && "timestamp" in resp && "value" in resp;
931
+ ) });
3003
932
  };
3004
- Jolokia.isResponseError = function(resp) {
3005
- if (!resp || typeof resp !== "object")
3006
- return false;
3007
- return "error_type" in resp && "error" in resp;
933
+ ChatbotPanelHeader = ({ isDrawerOpen, setIsDrawerOpen, title, hasCloseButton }) => {
934
+ const { setIsChatbotOpen } = (0, import_react8.useContext)(ChatbotContext);
935
+ const modelName = aiService.getModel()?.name;
936
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ChatbotHeader.default, { children: [
937
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ChatbotHeader.ChatbotHeaderMain, { children: [
938
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ChatbotHeader.ChatbotHeaderMenu, { "aria-expanded": isDrawerOpen, onMenuToggle: () => setIsDrawerOpen(!isDrawerOpen) }),
939
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ChatbotHeader.ChatbotHeaderTitle, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Content, { component: "h2", children: title }) })
940
+ ] }),
941
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ChatbotHeader.ChatbotHeaderActions, { children: [
942
+ modelName && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_core4.Label, { variant: "outline", children: modelName }),
943
+ hasCloseButton && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ChatbotHeader.ChatbotHeaderCloseButton, { onClick: () => setIsChatbotOpen(false) })
944
+ ] })
945
+ ] });
3008
946
  };
3009
- Jolokia.isResponseFetchError = function(resp) {
3010
- if (resp instanceof Response) {
3011
- return resp.status >= 400;
3012
- }
3013
- if (resp instanceof DOMException || resp instanceof TypeError) {
3014
- return true;
3015
- }
3016
- return false;
947
+ ChatbotPanelContent = () => {
948
+ const { messages, announcement } = (0, import_react8.useContext)(ChatbotContext);
949
+ const { username } = (0, import_react8.useContext)(import_ui2.PageContext);
950
+ const scrollToBottomRef = (0, import_react8.useRef)(null);
951
+ const welcomeTitle = `Hello, ${username}!`;
952
+ const welcomeDescription = "How can I help you manage or diagnose your Java application?";
953
+ (0, import_react8.useEffect)(() => {
954
+ if (messages.length > 2) {
955
+ scrollToBottomRef.current?.scrollIntoView({ behavior: "smooth" });
956
+ }
957
+ }, [messages]);
958
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ChatbotContent.default, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_MessageBox.default, { announcement, children: [
959
+ messages.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ChatbotWelcomePrompt.default, { title: welcomeTitle, description: welcomeDescription }),
960
+ messages.map((message, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react8.default.Fragment, { children: [
961
+ index === messages.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { ref: scrollToBottomRef }),
962
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_Message.default, { ...message }, message.id)
963
+ ] }, message.id))
964
+ ] }) });
3017
965
  };
3018
- GET_URL_EXTRACTORS = {
3019
- /**
3020
- * Function to prepare GET URL for `read` Jolokia request
3021
- * @param request Jolokia request object
3022
- * @returns URL configuration object for Jolokia `read` GET request
3023
- */
3024
- "read": function(request) {
3025
- const path = Array.isArray(request.path) ? request.path.map(Jolokia.escape).join("/") : request.path;
3026
- if (request.attribute == null) {
3027
- return { parts: [request.mbean, "*"], path };
3028
- } else {
3029
- return { parts: [request.mbean, request.attribute], path };
966
+ ChatbotPanelFooter = () => {
967
+ const { username } = (0, import_react8.useContext)(import_ui2.PageContext);
968
+ const { messages, setAnnouncement, isSendButtonDisabled, setIsSendButtonDisabled, updateConversations } = (0, import_react8.useContext)(ChatbotContext);
969
+ const messagesRef = (0, import_react8.useRef)(messages);
970
+ (0, import_react8.useEffect)(() => {
971
+ messagesRef.current = messages;
972
+ }, [messages]);
973
+ const handleSend = async (message) => {
974
+ if (!message.trim()) {
975
+ return;
3030
976
  }
3031
- },
3032
- /**
3033
- * Function to prepare GET URL for `write` Jolokia request
3034
- * @param request Jolokia request object
3035
- * @returns URL configuration object for Jolokia `write` GET request
3036
- */
3037
- "write": function(request) {
3038
- const path = Array.isArray(request.path) ? request.path.map(Jolokia.escape).join("/") : request.path;
3039
- return { parts: [request.mbean, request.attribute, valueToString(request.value)], path };
3040
- },
3041
- /**
3042
- * Function to prepare GET URL for `exec` Jolokia request
3043
- * @param request Jolokia request object
3044
- * @returns URL configuration object for Jolokia `exec` GET request
3045
- */
3046
- "exec": function(request) {
3047
- const ret = [request.mbean, request.operation];
3048
- if (request.arguments && request.arguments.length > 0) {
3049
- request.arguments.forEach(function(value) {
3050
- ret.push(valueToString(value));
3051
- });
977
+ log.debug("Send", messagesRef.current);
978
+ setIsSendButtonDisabled(true);
979
+ const newMessages = [];
980
+ newMessages.push(...messagesRef.current);
981
+ newMessages.push(aiService.createUserMessage(username, message));
982
+ newMessages.push(aiService.createLoadingBotMessage());
983
+ updateConversations(newMessages);
984
+ setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`);
985
+ log.debug("handleSend - new messages:", newMessages);
986
+ const dialogId = newMessages[0].id;
987
+ const loadedMessages = [...newMessages];
988
+ const onMessage = (intermediateAnswer) => {
989
+ loadedMessages.pop();
990
+ loadedMessages.push(aiService.toBotMessage(intermediateAnswer, true, ThinkInfo, ToolCallsInfo, ToolCallsApprove));
991
+ loadedMessages.push(aiService.createLoadingBotMessage());
992
+ updateConversations([...loadedMessages]);
993
+ };
994
+ const answer = await (newMessages.length === 2 ? aiService.newChat(dialogId, { message }, onMessage) : aiService.chat(dialogId, message, onMessage));
995
+ log.debug("handleSend - loaded messages:", loadedMessages);
996
+ loadedMessages.pop();
997
+ const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
998
+ loadedMessages.push(botMessage);
999
+ updateConversations([...loadedMessages]);
1000
+ setAnnouncement(`Message from Bot: ${answer}`);
1001
+ if (!aiService.hasToolCalls(answer)) {
1002
+ setIsSendButtonDisabled(false);
3052
1003
  }
3053
- return { parts: ret };
3054
- },
3055
- /**
3056
- * Function to prepare GET URL for `version` Jolokia request
3057
- * @param _request Jolokia request object
3058
- * @returns URL configuration object for Jolokia `version` GET request
3059
- */
3060
- "version": function(_request) {
3061
- return {};
3062
- },
3063
- /**
3064
- * Function to prepare GET URL for `search` Jolokia request
3065
- * @param request Jolokia request object
3066
- * @returns URL configuration object for Jolokia `search` GET request
3067
- */
3068
- "search": function(request) {
3069
- return { parts: [request.mbean] };
3070
- },
3071
- /**
3072
- * Function to prepare GET URL for `list` Jolokia request
3073
- * @param request Jolokia request object
3074
- * @returns URL configuration object for Jolokia `list` GET request
3075
- */
3076
- "list": function(request) {
3077
- return { path: request.path };
3078
- },
3079
- /**
3080
- * Function to prepare GET URL for `notification` Jolokia request
3081
- * @param request Jolokia request object
3082
- * @returns URL configuration object for Jolokia `notification` GET request
3083
- */
3084
- "notification": function(request) {
3085
- switch (request.command) {
3086
- case "register":
3087
- return { parts: ["register"] };
3088
- case "add": {
3089
- const ret = ["add", valueToString(request.client), valueToString(request.mode), valueToString(request.mbean)];
3090
- const extra = [];
3091
- if (request.handback) {
3092
- extra.push(valueToString(request.handback));
3093
- }
3094
- if (request.config) {
3095
- extra.push(valueToString(request.config));
3096
- } else if (extra.length) {
3097
- extra.push("{}");
3098
- }
3099
- if (request.filter) {
3100
- extra.push(valueToString(request.filter));
3101
- } else if (extra.length) {
3102
- extra.push(" ");
3103
- }
3104
- return { parts: ret.concat(extra.reverse()) };
1004
+ };
1005
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_ChatbotFooter.default, { children: [
1006
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1007
+ import_MessageBar.default,
1008
+ {
1009
+ onSendMessage: (m) => handleSend(String(m)),
1010
+ hasAttachButton: false,
1011
+ isSendButtonDisabled
3105
1012
  }
3106
- case "remove":
3107
- return { parts: ["remove", valueToString(request.client), valueToString(request.handle)] };
3108
- case "unregister":
3109
- return { parts: ["unregister", valueToString(request.client)] };
3110
- case "list":
3111
- return { parts: ["list", valueToString(request.client)] };
3112
- case "ping":
3113
- return { parts: ["ping", valueToString(request.client)] };
3114
- case "open":
3115
- return { parts: ["open", valueToString(request.client), valueToString(request.mode)] };
3116
- default:
3117
- throw new Error("Unknown command '" + request.command + "'");
3118
- }
1013
+ ),
1014
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_ChatbotFooter.ChatbotFootnote, { label: "AI may be inaccurate. Please verify important information." })
1015
+ ] });
1016
+ };
1017
+ }
1018
+ });
1019
+
1020
+ // src/ai-plugin/chat/Chat.tsx
1021
+ var import_Chatbot2, import_react_core5, import_jsx_runtime5, Chat;
1022
+ var init_Chat2 = __esm({
1023
+ "src/ai-plugin/chat/Chat.tsx"() {
1024
+ "use strict";
1025
+ import_Chatbot2 = require("@patternfly/chatbot/dist/dynamic/Chatbot");
1026
+ import_react_core5 = require("@patternfly/react-core");
1027
+ init_Chat();
1028
+ init_ChatbotPanel();
1029
+ init_context();
1030
+ import_jsx_runtime5 = require("react/jsx-runtime");
1031
+ Chat = () => {
1032
+ const chatbotContext = useChatbot();
1033
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatbotContext.Provider, { value: chatbotContext, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react_core5.PageSection, { id: "chat-content", hasBodyWrapper: false, isFilled: true, padding: { default: "noPadding" }, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ChatbotPanel, { title: "AI Chat", displayMode: import_Chatbot2.ChatbotDisplayMode.embedded }) }) });
1034
+ };
1035
+ }
1036
+ });
1037
+
1038
+ // src/ai-plugin/chat/ui.ts
1039
+ var ui_exports = {};
1040
+ __export(ui_exports, {
1041
+ Chat: () => Chat
1042
+ });
1043
+ var init_ui = __esm({
1044
+ "src/ai-plugin/chat/ui.ts"() {
1045
+ "use strict";
1046
+ init_Chat2();
1047
+ }
1048
+ });
1049
+
1050
+ // src/ai-plugin/jmx-ai/globals.ts
1051
+ var import_react12, pluginName3, pluginTitle3, pluginPath2, log3, PARAM_KEY_NODE_ID;
1052
+ var init_globals3 = __esm({
1053
+ "src/ai-plugin/jmx-ai/globals.ts"() {
1054
+ "use strict";
1055
+ import_react12 = require("@hawtio/react");
1056
+ pluginName3 = "hawtio-ai-jmx";
1057
+ pluginTitle3 = "AI JMX";
1058
+ pluginPath2 = "/ai-jmx";
1059
+ log3 = import_react12.Logger.get(pluginName3);
1060
+ PARAM_KEY_NODE_ID = "nid";
1061
+ }
1062
+ });
1063
+
1064
+ // src/ai-plugin/jmx-ai/context.ts
1065
+ function useMBeanTree() {
1066
+ const [tree, setTree] = (0, import_react14.useState)(import_react13.MBeanTree.createEmpty(pluginName3));
1067
+ const [loaded, setLoaded] = (0, import_react14.useState)(false);
1068
+ const { selectedNode, setSelectedNode } = (0, import_react14.useContext)(import_react13.PluginNodeSelectionContext);
1069
+ const navigate = (0, import_react_router.useNavigate)();
1070
+ const [searchParams, setSearchParams] = (0, import_react_router.useSearchParams)();
1071
+ const refSelectedNode = (0, import_react14.useRef)();
1072
+ refSelectedNode.current = selectedNode;
1073
+ const populateTree = async () => {
1074
+ const wkspTree = await import_react13.workspace.getTree();
1075
+ setTree(wkspTree);
1076
+ const nodeId = searchParams.get(PARAM_KEY_NODE_ID);
1077
+ if (nodeId && nodeId !== refSelectedNode.current?.id) {
1078
+ log3.debug("Restore selected node with nid:", nodeId);
1079
+ const urlNode = wkspTree.find((node) => node.id === nodeId);
1080
+ if (urlNode) {
1081
+ setSelectedNode(urlNode);
1082
+ refSelectedNode.current = urlNode;
1083
+ } else {
1084
+ log3.debug("Clear invalid nid:", nodeId);
1085
+ searchParams.delete(PARAM_KEY_NODE_ID);
1086
+ setSearchParams(searchParams);
3119
1087
  }
1088
+ }
1089
+ if (!refSelectedNode.current) return;
1090
+ const path = [...refSelectedNode.current.path()];
1091
+ wkspTree.forEach(path, (node) => {
1092
+ node.defaultExpanded = true;
1093
+ });
1094
+ const newSelected = wkspTree.navigate(...path);
1095
+ if (newSelected) {
1096
+ setSelectedNode(newSelected);
1097
+ navigate(pluginPathWithNodeId(newSelected, searchParams));
1098
+ } else {
1099
+ navigate(pluginPath2);
1100
+ }
1101
+ };
1102
+ (0, import_react14.useEffect)(() => {
1103
+ const loadTree = async () => {
1104
+ await populateTree();
1105
+ setLoaded(true);
1106
+ };
1107
+ const listener = () => {
1108
+ setLoaded(false);
1109
+ loadTree();
3120
1110
  };
1111
+ import_react13.eventService.onRefresh(listener);
1112
+ loadTree();
1113
+ return () => import_react13.eventService.removeListener(import_react13.EVENT_REFRESH, listener);
1114
+ }, []);
1115
+ return { tree, loaded, selectedNode, setSelectedNode };
1116
+ }
1117
+ function pluginPathWithNodeId(node, searchParams = new URLSearchParams(window.location.search)) {
1118
+ searchParams.set(PARAM_KEY_NODE_ID, node.id);
1119
+ const query = `?${searchParams.toString()}`;
1120
+ return { pathname: pluginPath2, search: query };
1121
+ }
1122
+ var import_react13, import_react14, import_react_router, MBeanTreeContext;
1123
+ var init_context2 = __esm({
1124
+ "src/ai-plugin/jmx-ai/context.ts"() {
1125
+ "use strict";
1126
+ import_react13 = require("@hawtio/react");
1127
+ import_react14 = require("react");
1128
+ import_react_router = require("react-router");
1129
+ init_globals3();
1130
+ MBeanTreeContext = (0, import_react14.createContext)({
1131
+ tree: import_react13.MBeanTree.createEmpty(pluginName3),
1132
+ loaded: false,
1133
+ selectedNode: null,
1134
+ setSelectedNode: () => {
1135
+ }
1136
+ });
1137
+ }
1138
+ });
1139
+
1140
+ // src/ai-plugin/jmx-ai/Jmx.css
1141
+ var init_Jmx = __esm({
1142
+ "src/ai-plugin/jmx-ai/Jmx.css"() {
1143
+ }
1144
+ });
1145
+
1146
+ // src/ai-plugin/jmx-ai/JmxContent.css
1147
+ var init_JmxContent = __esm({
1148
+ "src/ai-plugin/jmx-ai/JmxContent.css"() {
3121
1149
  }
3122
1150
  });
3123
1151
 
@@ -3190,12 +1218,12 @@ var init_util = __esm({
3190
1218
  });
3191
1219
 
3192
1220
  // src/ai-plugin/jmx-ai/attributes/attribute-service.ts
3193
- var import_react9, AttributeService, attributeService;
1221
+ var import_react15, AttributeService, attributeService;
3194
1222
  var init_attribute_service = __esm({
3195
1223
  "src/ai-plugin/jmx-ai/attributes/attribute-service.ts"() {
3196
1224
  "use strict";
3197
- import_react9 = require("@hawtio/react");
3198
- init_globals();
1225
+ import_react15 = require("@hawtio/react");
1226
+ init_globals3();
3199
1227
  init_util();
3200
1228
  AttributeService = class {
3201
1229
  handles = [];
@@ -3206,35 +1234,35 @@ var init_attribute_service = __esm({
3206
1234
  return request;
3207
1235
  }
3208
1236
  async read(mbean) {
3209
- return await import_react9.jolokiaService.readAttributes(mbean, this.requestOptions());
1237
+ return await import_react15.jolokiaService.readAttributes(mbean, this.requestOptions());
3210
1238
  }
3211
1239
  async readWithCallback(mbean, callback) {
3212
- const attrs = await import_react9.jolokiaService.readAttributes(mbean, this.requestOptions());
1240
+ const attrs = await import_react15.jolokiaService.readAttributes(mbean, this.requestOptions());
3213
1241
  callback(attrs);
3214
1242
  }
3215
1243
  async register(request, callback) {
3216
- const handle = await import_react9.jolokiaService.register(this.setupConfig(request), callback);
3217
- log.debug("Register handle:", handle);
1244
+ const handle = await import_react15.jolokiaService.register(this.setupConfig(request), callback);
1245
+ log3.debug("Register handle:", handle);
3218
1246
  this.handles.push(handle);
3219
1247
  }
3220
1248
  unregisterAll() {
3221
- log.debug("Unregister all handles:", this.handles);
3222
- this.handles.forEach((handle) => import_react9.jolokiaService.unregister(handle));
1249
+ log3.debug("Unregister all handles:", this.handles);
1250
+ this.handles.forEach((handle) => import_react15.jolokiaService.unregister(handle));
3223
1251
  this.handles = [];
3224
1252
  }
3225
1253
  async buildUrl(mbean, attribute) {
3226
- const jolokiaUrl = await import_react9.jolokiaService.getFullJolokiaUrl();
1254
+ const jolokiaUrl = await import_react15.jolokiaService.getFullJolokiaUrl();
3227
1255
  return `${jolokiaUrl}/read/${escapeMBean(mbean)}/${attribute}`;
3228
1256
  }
3229
1257
  async canInvoke(mbean, attribute, type) {
3230
1258
  return true;
3231
1259
  }
3232
1260
  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}` });
1261
+ await import_react15.jolokiaService.writeAttribute(mbeanName, attribute, value, this.requestOptions());
1262
+ import_react15.eventService.notify({ type: "success", message: `Updated attribute: ${attribute}` });
3235
1263
  }
3236
1264
  async bulkRequest(requests) {
3237
- return import_react9.jolokiaService.bulkRequest(requests.map(this.setupConfig));
1265
+ return import_react15.jolokiaService.bulkRequest(requests.map(this.setupConfig));
3238
1266
  }
3239
1267
  };
3240
1268
  attributeService = new AttributeService();
@@ -3242,34 +1270,37 @@ var init_attribute_service = __esm({
3242
1270
  });
3243
1271
 
3244
1272
  // src/ai-plugin/jmx-ai/attributes/Attributes.tsx
3245
- var import_react10, import_ui2, import_react_core3, import_react_icons, import_react_table, import_react11, import_jsx_runtime3, Attributes, AiJmxToolbar;
1273
+ var import_react16, import_ui3, import_react_core7, import_react_icons, import_react_table2, import_jolokia, import_react17, import_jsx_runtime7, Attributes, AiJmxToolbar;
3246
1274
  var init_Attributes = __esm({
3247
1275
  "src/ai-plugin/jmx-ai/attributes/Attributes.tsx"() {
3248
1276
  "use strict";
3249
- import_react10 = require("@hawtio/react");
3250
- import_ui2 = require("@hawtio/react/ui");
3251
- import_react_core3 = require("@patternfly/react-core");
1277
+ import_react16 = require("@hawtio/react");
1278
+ import_ui3 = require("@hawtio/react/ui");
1279
+ import_react_core7 = require("@patternfly/react-core");
3252
1280
  import_react_icons = require("@patternfly/react-icons");
3253
- import_react_table = require("@patternfly/react-table");
3254
- init_jolokia();
3255
- import_react11 = require("react");
3256
- init_ai_service();
1281
+ import_react_table2 = require("@patternfly/react-table");
1282
+ import_jolokia = __toESM(require("jolokia.js"));
1283
+ import_react17 = require("react");
3257
1284
  init_context();
3258
- init_DiagnosisChatbot();
3259
- init_globals();
1285
+ init_ThinkInfo();
1286
+ init_ToolCallsApprove();
1287
+ init_ToolCallsInfo();
1288
+ init_ai_service();
1289
+ init_context2();
1290
+ init_globals3();
3260
1291
  init_jmx_ai_service();
3261
1292
  init_util();
3262
1293
  init_attribute_service();
3263
- import_jsx_runtime3 = require("react/jsx-runtime");
1294
+ import_jsx_runtime7 = require("react/jsx-runtime");
3264
1295
  Attributes = () => {
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)(() => {
1296
+ const { selectedNode } = (0, import_react17.useContext)(MBeanTreeContext);
1297
+ const [attributes, setAttributes] = (0, import_react17.useState)({});
1298
+ const [isReading, setIsReading] = (0, import_react17.useState)(true);
1299
+ const [isModalOpen, setIsModalOpen] = (0, import_react17.useState)(false);
1300
+ const [sortDirection, setSortDirection] = (0, import_react17.useState)("asc");
1301
+ const [selected, setSelected] = (0, import_react17.useState)({ name: "", value: "" });
1302
+ const [reload, setReload] = (0, import_react17.useState)(false);
1303
+ (0, import_react17.useEffect)(() => {
3273
1304
  if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {
3274
1305
  return;
3275
1306
  }
@@ -3282,14 +1313,14 @@ var init_Attributes = __esm({
3282
1313
  attributeService.register(
3283
1314
  { type: "read", mbean: objectName },
3284
1315
  (response) => {
3285
- if (response && !Jolokia.isError(response)) {
1316
+ if (response && !import_jolokia.default.isError(response)) {
3286
1317
  setAttributes(response.value);
3287
1318
  }
3288
1319
  }
3289
1320
  );
3290
1321
  return () => attributeService.unregisterAll();
3291
1322
  }, [selectedNode]);
3292
- (0, import_react11.useEffect)(() => {
1323
+ (0, import_react17.useEffect)(() => {
3293
1324
  if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName || !reload) {
3294
1325
  return;
3295
1326
  }
@@ -3305,14 +1336,14 @@ var init_Attributes = __esm({
3305
1336
  return null;
3306
1337
  }
3307
1338
  if (isReading) {
3308
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react10.HawtioLoadingCard, {});
1339
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react16.HawtioLoadingCard, {});
3309
1340
  }
3310
1341
  const rows = Object.entries(attributes).map(([name, value]) => ({
3311
1342
  name,
3312
1343
  value: isObject(value) ? JSON.stringify(value) : String(value)
3313
1344
  }));
3314
1345
  if (rows.length === 0) {
3315
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react10.HawtioEmptyCard, { message: "This MBean has no attributes." });
1346
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react16.HawtioEmptyCard, { message: "This MBean has no attributes." });
3316
1347
  }
3317
1348
  const selectAttribute = (attribute) => {
3318
1349
  setSelected(attribute);
@@ -3332,8 +1363,8 @@ var init_Attributes = __esm({
3332
1363
  },
3333
1364
  columnIndex: 0
3334
1365
  });
3335
- const panelContent = /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
3336
- import_react10.AttributeModal,
1366
+ const panelContent = /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1367
+ import_react16.AttributeModal,
3337
1368
  {
3338
1369
  isOpen: isModalOpen,
3339
1370
  onClose: () => setIsModalOpen(false),
@@ -3341,34 +1372,34 @@ var init_Attributes = __esm({
3341
1372
  input: selected
3342
1373
  }
3343
1374
  );
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" })
1375
+ const attributesTable = /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { id: "attribute-table-with-panel", children: [
1376
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(AiJmxToolbar, { attributes }),
1377
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_table2.Table, { "aria-label": "Attributes", variant: "compact", children: [
1378
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_table2.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_react_table2.Tr, { children: [
1379
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_table2.Th, { sort: getSortParams(), children: "Attribute" }),
1380
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_table2.Th, { children: "Value" })
3350
1381
  ] }) }),
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)(
3352
- import_react_table.Tr,
1382
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_table2.Tbody, { children: rows.sort((a, b) => objectSorter(a.name, b.name, sortDirection === "desc")).map((att, index) => /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
1383
+ import_react_table2.Tr,
3353
1384
  {
3354
1385
  isClickable: true,
3355
1386
  isRowSelected: selected.name === att.name,
3356
1387
  onRowClick: () => selectAttribute(att),
3357
1388
  children: [
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 })
1389
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_table2.Td, { children: att.name }),
1390
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_table2.Td, { children: att.value })
3360
1391
  ]
3361
1392
  },
3362
1393
  att.name + "-" + index
3363
1394
  )) })
3364
1395
  ] })
3365
1396
  ] });
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 }) }) }) });
1397
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.Panel, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.Drawer, { isExpanded: isModalOpen, className: "pf-m-inline-on-2xl", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.DrawerContentBody, { hasPadding: true, children: attributesTable }) }) }) });
3367
1398
  };
3368
1399
  AiJmxToolbar = ({ attributes }) => {
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);
1400
+ const { selectedNode } = (0, import_react17.useContext)(MBeanTreeContext);
1401
+ const { username } = (0, import_react17.useContext)(import_ui3.PageContext);
1402
+ const { setAnnouncement, setIsChatbotOpen, updateConversations } = (0, import_react17.useContext)(ChatbotContext);
3372
1403
  if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {
3373
1404
  return null;
3374
1405
  }
@@ -3376,7 +1407,7 @@ var init_Attributes = __esm({
3376
1407
  const diagnose = async () => {
3377
1408
  setIsChatbotOpen(true);
3378
1409
  const attrsValue = JSON.stringify(attributes);
3379
- log.debug("Attributes:", attrsValue);
1410
+ log3.debug("Attributes:", attrsValue);
3380
1411
  const systemMessage = jmxAiService.systemMessage();
3381
1412
  const diagnoseMessage = jmxAiService.diagnoseMessage(objectName, attrsValue);
3382
1413
  const newMessages = [];
@@ -3384,19 +1415,19 @@ var init_Attributes = __esm({
3384
1415
  newMessages.push(aiService.createLoadingBotMessage());
3385
1416
  updateConversations(newMessages, `Diagnose ${objectName}`);
3386
1417
  setAnnouncement("Diagnosis in progress...");
3387
- log.debug("diagnose - new messages:", newMessages);
1418
+ log3.debug("diagnose - new messages:", newMessages);
3388
1419
  const dialogId = newMessages[0].id;
3389
- const answer = await aiService.newChat(dialogId, diagnoseMessage, systemMessage);
1420
+ const answer = await aiService.newChat(dialogId, { message: diagnoseMessage, system: systemMessage });
3390
1421
  const loadedMessages = [];
3391
1422
  loadedMessages.push(...newMessages);
3392
- log.debug("diagnose - loaded messages:", loadedMessages);
1423
+ log3.debug("diagnose - loaded messages:", loadedMessages);
3393
1424
  loadedMessages.pop();
3394
- const botMessage = aiService.toBotMessage(answer, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
1425
+ const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove);
3395
1426
  loadedMessages.push(botMessage);
3396
1427
  updateConversations(loadedMessages);
3397
1428
  setAnnouncement("Diagnosis complete.");
3398
1429
  };
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" }) }) }) });
1430
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.Toolbar, { id: "ai-jmx-toolbar", children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.ToolbarContent, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.ToolbarItem, { children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_core7.Button, { variant: "primary", size: "sm", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_react_icons.MonitoringIcon, {}), onClick: diagnose, children: "Diagnose" }) }) }) });
3400
1431
  };
3401
1432
  }
3402
1433
  });
@@ -3410,30 +1441,32 @@ var init_attributes = __esm({
3410
1441
  });
3411
1442
 
3412
1443
  // src/ai-plugin/jmx-ai/JmxContent.tsx
3413
- var import_react12, import_react_core4, import_popper_core, import_cubes_icon, import_react13, import_react_router_dom2, import_jsx_runtime4, JmxContent;
1444
+ var import_react18, import_Chatbot3, import_react_core8, import_popper_core, import_cubes_icon, import_react19, import_react_router2, import_jsx_runtime8, JmxContent;
3414
1445
  var init_JmxContent2 = __esm({
3415
1446
  "src/ai-plugin/jmx-ai/JmxContent.tsx"() {
3416
1447
  "use strict";
3417
- import_react12 = require("@hawtio/react");
3418
- import_react_core4 = require("@patternfly/react-core");
1448
+ import_react18 = require("@hawtio/react");
1449
+ import_Chatbot3 = require("@patternfly/chatbot/dist/dynamic/Chatbot");
1450
+ import_react_core8 = require("@patternfly/react-core");
3419
1451
  import_popper_core = require("@patternfly/react-core/dist/esm/helpers/Popper/thirdparty/popper-core");
3420
1452
  import_cubes_icon = require("@patternfly/react-icons/dist/esm/icons/cubes-icon");
3421
- import_react13 = __toESM(require("react"));
3422
- import_react_router_dom2 = require("react-router-dom");
3423
- init_DiagnosisChatbot();
1453
+ import_react19 = __toESM(require("react"));
1454
+ import_react_router2 = require("react-router");
1455
+ init_ChatbotPanel();
1456
+ init_context();
3424
1457
  init_JmxContent();
3425
1458
  init_attributes();
3426
- init_context();
3427
- init_globals();
3428
- import_jsx_runtime4 = require("react/jsx-runtime");
1459
+ init_context2();
1460
+ init_globals3();
1461
+ import_jsx_runtime8 = require("react/jsx-runtime");
3429
1462
  JmxContent = () => {
3430
- const { selectedNode } = (0, import_react13.useContext)(MBeanTreeContext);
3431
- const { pathname, search } = (0, import_react_router_dom2.useLocation)();
1463
+ const { selectedNode } = (0, import_react19.useContext)(MBeanTreeContext);
1464
+ const { pathname, search } = (0, import_react_router2.useLocation)();
3432
1465
  const chatbotContext = useChatbot();
3433
1466
  const { isChatbotOpen, setIsChatbotOpen } = chatbotContext;
3434
- const drawerRef = (0, import_react13.useRef)(void 0);
1467
+ const drawerRef = (0, import_react19.useRef)(void 0);
3435
1468
  if (!selectedNode) {
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" }) });
1469
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.PageSection, { hasBodyWrapper: false, isFilled: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.EmptyState, { headingLevel: "h1", icon: import_cubes_icon.CubesIcon, titleText: "Select MBean", variant: "full" }) });
3437
1470
  }
3438
1471
  const mBeanApplicable = (node) => Boolean(node.objectName);
3439
1472
  const mBeanCollectionApplicable = (node) => Boolean(node.children?.every((child) => child.objectName));
@@ -3441,42 +1474,42 @@ var init_JmxContent2 = __esm({
3441
1474
  const tableSelector = (node) => {
3442
1475
  const tablePriorityList = [
3443
1476
  { condition: mBeanApplicable, element: Attributes },
3444
- { condition: mBeanCollectionApplicable, element: import_react12.AttributeTable }
1477
+ { condition: mBeanCollectionApplicable, element: import_react18.AttributeTable }
3445
1478
  ];
3446
- return tablePriorityList.find((entry) => entry.condition(node))?.element ?? import_react12.JmxContentMBeans;
1479
+ return tablePriorityList.find((entry) => entry.condition(node))?.element ?? import_react18.JmxContentMBeans;
3447
1480
  };
3448
1481
  const allNavItems = [
3449
1482
  { id: "attributes", title: "Attributes", component: tableSelector(selectedNode), isApplicable: () => true },
3450
- { id: "operations", title: "Operations", component: import_react12.Operations, isApplicable: mBeanApplicable },
3451
- { id: "chart", title: "Chart", component: import_react12.Chart, isApplicable: hasAnyApplicableMBean }
1483
+ { id: "operations", title: "Operations", component: import_react18.Operations, isApplicable: mBeanApplicable },
1484
+ { id: "chart", title: "Chart", component: import_react18.Chart, isApplicable: hasAnyApplicableMBean }
3452
1485
  ];
3453
1486
  const navItems = allNavItems.filter((nav) => nav.isApplicable(selectedNode));
3454
1487
  const searchWithNid = pluginPathWithNodeId(selectedNode, new URLSearchParams(search)).search;
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: [
1488
+ const mbeanNav = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.Nav, { "aria-label": "MBean Nav", variant: "horizontal-subnav", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.NavList, { children: navItems.map((nav) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.NavItem, { isActive: pathname === `${pluginPath2}/${nav.id}`, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_router2.NavLink, { to: { pathname: nav.id, search }, children: nav.title }) }, nav.id)) }) });
1489
+ const mbeanRoutes = navItems.map((nav) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_router2.Route, { path: nav.id, element: import_react19.default.createElement(nav.component) }, nav.id));
1490
+ const jmxAiToolbar = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.Toolbar, { id: "jmx-ai-toolbar", style: { float: import_popper_core.right }, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.ToolbarItem, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.Button, { variant: "secondary", size: "sm", onClick: () => setIsChatbotOpen(!isChatbotOpen), children: "Chat" }) }) });
1491
+ const jmxContent = /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_core8.PageGroup, { id: "jmx-content", children: [
1492
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_core8.PageSection, { id: "jmx-content-header", hasBodyWrapper: false, children: [
3460
1493
  jmxAiToolbar,
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 })
1494
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.Title, { headingLevel: "h1", children: selectedNode.name }),
1495
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.Content, { component: "small", children: selectedNode.objectName })
3463
1496
  ] }),
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,
1497
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.PageSection, { type: "tabs", hasBodyWrapper: false, children: mbeanNav }),
1498
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1499
+ import_react_core8.PageSection,
3467
1500
  {
3468
1501
  id: "jmx-content-main",
3469
1502
  padding: { default: "noPadding" },
3470
1503
  hasOverflowScroll: true,
3471
1504
  "aria-label": "jmx-content-main",
3472
1505
  hasBodyWrapper: false,
3473
- children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_react_router_dom2.Routes, { children: [
1506
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_router2.Routes, { children: [
3474
1507
  mbeanRoutes,
3475
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
3476
- import_react_router_dom2.Route,
1508
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1509
+ import_react_router2.Route,
3477
1510
  {
3478
1511
  path: "/",
3479
- element: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_react_router_dom2.Navigate, { to: { pathname: navItems[0]?.id ?? "", search: searchWithNid } })
1512
+ element: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_router2.Navigate, { to: { pathname: navItems[0]?.id ?? "", search: searchWithNid } })
3480
1513
  },
3481
1514
  "root"
3482
1515
  )
@@ -3487,8 +1520,8 @@ var init_JmxContent2 = __esm({
3487
1520
  const onDrawerExpand = () => {
3488
1521
  drawerRef.current && drawerRef.current.focus();
3489
1522
  };
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 }) }) }) });
1523
+ const panelContent = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.DrawerPanelContent, { isResizable: true, defaultSize: "500px", minSize: "200px", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.DrawerPanelBody, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChatbotPanel, { title: "AI Diagnosis", displayMode: import_Chatbot3.ChatbotDisplayMode.drawer }) }) });
1524
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(ChatbotContext.Provider, { value: chatbotContext, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.Drawer, { isExpanded: isChatbotOpen, isInline: true, onExpand: onDrawerExpand, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.DrawerContent, { panelContent, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core8.DrawerContentBody, { children: jmxContent }) }) }) });
3492
1525
  };
3493
1526
  }
3494
1527
  });
@@ -3500,23 +1533,23 @@ var init_JmxTreeView = __esm({
3500
1533
  });
3501
1534
 
3502
1535
  // src/ai-plugin/jmx-ai/JmxTreeView.tsx
3503
- var import_react14, import_react_core5, import_react15, import_react_router_dom3, import_jsx_runtime5, JmxTreeView;
1536
+ var import_react20, import_react_core9, import_react21, import_react_router3, import_jsx_runtime9, JmxTreeView;
3504
1537
  var init_JmxTreeView2 = __esm({
3505
1538
  "src/ai-plugin/jmx-ai/JmxTreeView.tsx"() {
3506
1539
  "use strict";
3507
- import_react14 = require("@hawtio/react");
3508
- import_react_core5 = require("@patternfly/react-core");
3509
- import_react15 = require("react");
3510
- import_react_router_dom3 = require("react-router-dom");
1540
+ import_react20 = require("@hawtio/react");
1541
+ import_react_core9 = require("@patternfly/react-core");
1542
+ import_react21 = require("react");
1543
+ import_react_router3 = require("react-router");
3511
1544
  init_JmxTreeView();
3512
- init_context();
3513
- import_jsx_runtime5 = require("react/jsx-runtime");
1545
+ init_context2();
1546
+ import_jsx_runtime9 = require("react/jsx-runtime");
3514
1547
  JmxTreeView = () => {
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());
3518
- const navigate = (0, import_react_router_dom3.useNavigate)();
3519
- (0, import_react15.useEffect)(() => {
1548
+ const { tree, selectedNode, setSelectedNode } = (0, import_react21.useContext)(MBeanTreeContext);
1549
+ const [expanded, setExpanded] = (0, import_react21.useState)(0 /* Default */);
1550
+ const [filteredTree, setFilteredTree] = (0, import_react21.useState)(tree.getTree());
1551
+ const navigate = (0, import_react_router3.useNavigate)();
1552
+ (0, import_react21.useEffect)(() => {
3520
1553
  setFilteredTree(tree.getTree());
3521
1554
  }, [tree]);
3522
1555
  const onSearch = (event) => {
@@ -3524,7 +1557,7 @@ var init_JmxTreeView2 = __esm({
3524
1557
  setExpanded(0 /* Default */);
3525
1558
  const input = event.target.value;
3526
1559
  if (!input) setFilteredTree(tree.getTree());
3527
- const treeElements = import_react14.MBeanTree.filter(tree.getTree(), (node) => node.name.toLowerCase().includes(input.toLowerCase()));
1560
+ const treeElements = import_react20.MBeanTree.filter(tree.getTree(), (node) => node.name.toLowerCase().includes(input.toLowerCase()));
3528
1561
  if (treeElements.length === 0) setFilteredTree(tree.getTree());
3529
1562
  else {
3530
1563
  setFilteredTree(treeElements);
@@ -3549,8 +1582,8 @@ var init_JmxTreeView2 = __esm({
3549
1582
  return {};
3550
1583
  }
3551
1584
  };
3552
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
3553
- import_react_core5.TreeView,
1585
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1586
+ import_react_core9.TreeView,
3554
1587
  {
3555
1588
  id: "jmx-tree-view",
3556
1589
  data: filteredTree,
@@ -3559,7 +1592,7 @@ var init_JmxTreeView2 = __esm({
3559
1592
  activeItems: selectedNode ? [selectedNode] : [],
3560
1593
  ...expandedProp(),
3561
1594
  onSelect,
3562
- toolbar: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_react14.PluginTreeViewToolbar, { onSearch, onSetExpanded: setAllExpanded })
1595
+ toolbar: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_react20.PluginTreeViewToolbar, { onSearch, onSetExpanded: setAllExpanded })
3563
1596
  }
3564
1597
  );
3565
1598
  };
@@ -3567,42 +1600,42 @@ var init_JmxTreeView2 = __esm({
3567
1600
  });
3568
1601
 
3569
1602
  // src/ai-plugin/jmx-ai/Jmx.tsx
3570
- var import_react_core6, import_cubes_icon2, import_jsx_runtime6, Jmx;
1603
+ var import_react_core10, import_cubes_icon2, import_react_split, import_jsx_runtime10, Jmx;
3571
1604
  var init_Jmx2 = __esm({
3572
1605
  "src/ai-plugin/jmx-ai/Jmx.tsx"() {
3573
1606
  "use strict";
3574
- import_react_core6 = require("@patternfly/react-core");
1607
+ import_react_core10 = require("@patternfly/react-core");
3575
1608
  import_cubes_icon2 = require("@patternfly/react-icons/dist/esm/icons/cubes-icon");
3576
- init_react_split_es();
3577
- init_context();
1609
+ import_react_split = __toESM(require("react-split"));
1610
+ init_context2();
3578
1611
  init_Jmx();
3579
1612
  init_JmxContent2();
3580
1613
  init_JmxTreeView2();
3581
- import_jsx_runtime6 = require("react/jsx-runtime");
1614
+ import_jsx_runtime10 = require("react/jsx-runtime");
3582
1615
  Jmx = () => {
3583
1616
  const { tree, loaded, selectedNode, setSelectedNode } = useMBeanTree();
3584
1617
  if (!loaded) {
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" }) });
1618
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_core10.PageSection, { hasBodyWrapper: false, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_core10.Spinner, { "aria-label": "Loading MBean tree" }) });
3586
1619
  }
3587
1620
  if (tree.isEmpty()) {
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" }) });
1621
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_core10.PageSection, { hasBodyWrapper: false, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_react_core10.EmptyState, { headingLevel: "h1", icon: import_cubes_icon2.CubesIcon, titleText: "No MBeans found", variant: "full" }) });
3589
1622
  }
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, {}) })
1623
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(MBeanTreeContext.Provider, { value: { tree, loaded, selectedNode, setSelectedNode }, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_react_split.default, { className: "jmx-split", sizes: [30, 70], minSize: 200, gutterSize: 5, children: [
1624
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(JmxTreeView, {}) }),
1625
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(JmxContent, {}) })
3593
1626
  ] }) });
3594
1627
  };
3595
1628
  }
3596
1629
  });
3597
1630
 
3598
1631
  // src/ai-plugin/jmx-ai/ui.ts
3599
- var ui_exports = {};
3600
- __export(ui_exports, {
1632
+ var ui_exports2 = {};
1633
+ __export(ui_exports2, {
3601
1634
  Jmx: () => Jmx,
3602
1635
  JmxContent: () => JmxContent,
3603
1636
  JmxTreeView: () => JmxTreeView
3604
1637
  });
3605
- var init_ui = __esm({
1638
+ var init_ui2 = __esm({
3606
1639
  "src/ai-plugin/jmx-ai/ui.ts"() {
3607
1640
  "use strict";
3608
1641
  init_Jmx2();
@@ -3617,25 +1650,53 @@ __export(index_exports, {
3617
1650
  plugin: () => plugin
3618
1651
  });
3619
1652
  module.exports = __toCommonJS(index_exports);
3620
- var import_react17 = require("@hawtio/react");
1653
+ var import_react23 = require("@hawtio/react");
3621
1654
  var import_main = require("@patternfly/chatbot/dist/css/main.css");
3622
1655
 
1656
+ // src/ai-plugin/chat/index.ts
1657
+ var import_react9 = require("@hawtio/react");
1658
+ init_globals();
1659
+ var order = 42;
1660
+ var aiChat = () => {
1661
+ log.info("Loading", pluginName);
1662
+ import_react9.hawtio.addDeferredPlugin(pluginName, async () => {
1663
+ return Promise.resolve().then(() => (init_ui(), ui_exports)).then(({ Chat: Chat2 }) => {
1664
+ return {
1665
+ id: pluginName,
1666
+ title: pluginTitle,
1667
+ path: pluginPath,
1668
+ order,
1669
+ component: Chat2,
1670
+ isActive: async () => true
1671
+ };
1672
+ });
1673
+ });
1674
+ };
1675
+
3623
1676
  // src/ai-plugin/common/index.ts
3624
- var import_react4 = require("@hawtio/react");
1677
+ var import_react11 = require("@hawtio/react");
3625
1678
 
3626
1679
  // src/ai-plugin/common/AiPreferences.tsx
3627
- var import_react_core = require("@patternfly/react-core");
1680
+ var import_react_core6 = require("@patternfly/react-core");
3628
1681
  var import_eye_icon = __toESM(require("@patternfly/react-icons/dist/esm/icons/eye-icon"));
3629
1682
  var import_eye_slash_icon = __toESM(require("@patternfly/react-icons/dist/esm/icons/eye-slash-icon"));
3630
- var import_react2 = require("react");
1683
+ var import_react_table = require("@patternfly/react-table");
1684
+ var import_react10 = require("react");
3631
1685
  init_ai_model();
3632
1686
  init_ai_preferences_service();
3633
- var import_jsx_runtime = require("react/jsx-runtime");
1687
+ init_tools();
1688
+ var import_jsx_runtime6 = require("react/jsx-runtime");
3634
1689
  var AiPreferences = () => {
3635
- const [options, setOptions] = (0, import_react2.useState)(aiPreferencesService.loadOptions());
3636
- const [provider, setProvider] = (0, import_react2.useState)(options.model.provider);
3637
- const [models, setModels] = (0, import_react2.useState)(MODELS.filter((m) => m.provider === provider));
3638
- const [passwordHidden, setPasswordHidden] = (0, import_react2.useState)(true);
1690
+ const [options, setOptions] = (0, import_react10.useState)(aiPreferencesService.loadOptions());
1691
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.CardBody, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core6.Form, { id: "ai-prefs-form", isHorizontal: true, children: [
1692
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(ModelForm, { options, setOptions }),
1693
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(PermissionForm, { options, setOptions })
1694
+ ] }) });
1695
+ };
1696
+ var ModelForm = ({ options, setOptions }) => {
1697
+ const [provider, setProvider] = (0, import_react10.useState)(options.model.provider);
1698
+ const [models, setModels] = (0, import_react10.useState)(MODELS.filter((m) => m.provider === provider));
1699
+ const [passwordHidden, setPasswordHidden] = (0, import_react10.useState)(true);
3639
1700
  const updateProvider = (provider2) => {
3640
1701
  setProvider(provider2);
3641
1702
  setModels(MODELS.filter((m) => m.provider === provider2));
@@ -3651,126 +1712,161 @@ var AiPreferences = () => {
3651
1712
  aiPreferencesService.saveOptions({ token: updated });
3652
1713
  setOptions({ ...options, token: updated });
3653
1714
  };
3654
- return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.CardBody, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.Form, { isHorizontal: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_core.FormSection, { title: "AI", titleElement: "h2", children: [
3655
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.FormGroup, { fieldId: "ai-prefs-form-provider", label: "Provider", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3656
- import_react_core.FormSelect,
1715
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core6.FormSection, { title: "Model", titleElement: "h2", children: [
1716
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.FormGroup, { fieldId: "ai-prefs-form-provider", label: "Provider", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1717
+ import_react_core6.FormSelect,
3657
1718
  {
3658
1719
  id: "ai-prefs-form-provider-input",
3659
1720
  "aria-label": "Form Select Provider",
3660
1721
  value: provider,
3661
- onChange: (_, provider2) => updateProvider(provider2),
3662
- children: PROVIDERS.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.FormSelectOption, { value: p, label: p }, i))
1722
+ onChange: (_, p) => updateProvider(p),
1723
+ children: PROVIDERS.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.FormSelectOption, { value: p, label: p }, i))
3663
1724
  }
3664
1725
  ) }),
3665
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.FormGroup, { fieldId: "ai-prefs-form-model", label: "Model", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3666
- import_react_core.FormSelect,
1726
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.FormGroup, { fieldId: "ai-prefs-form-model", label: "Model", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1727
+ import_react_core6.FormSelect,
3667
1728
  {
3668
1729
  id: "ai-prefs-form-model-input",
3669
1730
  "aria-label": "Form Select Model",
3670
1731
  value: options.model.id,
3671
1732
  onChange: (_, id) => updateModel(id),
3672
- children: models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.FormSelectOption, { value: m.id, label: m.name }, m.id))
1733
+ children: models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.FormSelectOption, { value: m.id, label: m.name }, m.id))
3673
1734
  }
3674
1735
  ) }),
3675
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.FormGroup, { fieldId: "ai-prefs-form-token", label: "API Key / Token (optional)", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_react_core.InputGroup, { children: [
3676
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.InputGroupItem, { isFill: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3677
- import_react_core.TextInput,
1736
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.FormGroup, { fieldId: "ai-prefs-form-token", label: "API Key / Token (optional)", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core6.InputGroup, { children: [
1737
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.InputGroupItem, { isFill: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1738
+ import_react_core6.TextInput,
3678
1739
  {
3679
1740
  id: "ai-prefs-form-token-input",
3680
1741
  "aria-label": "Form Select Token",
3681
1742
  type: passwordHidden ? "password" : "text",
3682
1743
  value: options.token,
3683
- onChange: (_, token) => updateToken(token)
1744
+ onChange: (_, t) => updateToken(t)
3684
1745
  }
3685
1746
  ) }),
3686
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_react_core.InputGroupItem, { children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
3687
- import_react_core.Button,
1747
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.InputGroupItem, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1748
+ import_react_core6.Button,
3688
1749
  {
3689
1750
  variant: "control",
3690
1751
  onClick: () => setPasswordHidden(!passwordHidden),
3691
1752
  "aria-label": passwordHidden ? "Show password" : "Hide password",
3692
- children: passwordHidden ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_eye_icon.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_eye_slash_icon.default, {})
1753
+ children: passwordHidden ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_eye_icon.default, {}) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_eye_slash_icon.default, {})
3693
1754
  }
3694
1755
  ) })
3695
1756
  ] }) })
3696
- ] }) }) });
1757
+ ] });
1758
+ };
1759
+ var PermissionForm = ({ options, setOptions }) => {
1760
+ const maxAutoToolSteps = options.maxAutoToolSteps ?? DEFAULT_MAX_AUTO_TOOL_STEPS;
1761
+ const toolPermissions = options.toolPermissions ?? DEFAULT_TOOL_PERMISSIONS;
1762
+ const updateMaxAutoToolSteps = (updated) => {
1763
+ aiPreferencesService.saveOptions({ maxAutoToolSteps: updated });
1764
+ setOptions({ ...options, maxAutoToolSteps: updated });
1765
+ };
1766
+ const updatePermission = (tool, updated) => {
1767
+ const updatedPermissions = { ...toolPermissions, [tool]: updated };
1768
+ aiPreferencesService.saveOptions({ toolPermissions: updatedPermissions });
1769
+ setOptions({ ...options, toolPermissions: updatedPermissions });
1770
+ };
1771
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core6.FormSection, { title: "Permission control", titleElement: "h2", children: [
1772
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.FormGroup, { fieldId: "ai-prefs-form-max-steps", label: "Max auto-approve steps", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1773
+ import_react_core6.NumberInput,
1774
+ {
1775
+ id: "ai-prefs-form-max-steps-input",
1776
+ "aria-label": "Form select max auto-approve steps",
1777
+ value: options.maxAutoToolSteps,
1778
+ min: 1,
1779
+ max: 100,
1780
+ onMinus: () => updateMaxAutoToolSteps(Math.max(1, maxAutoToolSteps - 1)),
1781
+ onPlus: () => updateMaxAutoToolSteps(Math.min(100, maxAutoToolSteps + 1)),
1782
+ onChange: (e) => {
1783
+ const value = parseInt(e.target.value);
1784
+ if (!isNaN(value) && value >= 1 && value <= 100) {
1785
+ updateMaxAutoToolSteps(value);
1786
+ }
1787
+ }
1788
+ }
1789
+ ) }),
1790
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_core6.FormGroup, { fieldId: "ai-prefs-form-tool-permissions", style: { display: "flex" }, children: [
1791
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_core6.Content, { component: "small", children: "Enable auto-approve to allow a tool to run without asking for confirmation each time." }),
1792
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
1793
+ import_react_table.Table,
1794
+ {
1795
+ "aria-label": "Tool permissions",
1796
+ variant: "compact",
1797
+ borders: false,
1798
+ isStriped: true,
1799
+ isStickyHeader: true,
1800
+ style: { marginTop: "0.5rem" },
1801
+ children: [
1802
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_table.Tr, { children: [
1803
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Th, { modifier: "fitContent", children: "Tool" }),
1804
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Th, { modifier: "wrap", children: "Description" }),
1805
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Th, { modifier: "fitContent", children: "Auto-approve" })
1806
+ ] }) }),
1807
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Tbody, { children: WORKSPACE_TOOLS_META.map(({ name, description }) => /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(import_react_table.Tr, { children: [
1808
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Td, { dataLabel: "Tool", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("b", { children: name }) }),
1809
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Td, { dataLabel: "Description", children: description }),
1810
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_react_table.Td, { dataLabel: "Auto-approve", textCenter: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1811
+ import_react_core6.Switch,
1812
+ {
1813
+ id: `ai-prefs-tool-switch-${name}`,
1814
+ "aria-label": `Auto-approve ${name}`,
1815
+ isChecked: toolPermissions[name] ?? false,
1816
+ onChange: (_, checked) => updatePermission(name, checked)
1817
+ }
1818
+ ) })
1819
+ ] }, name)) })
1820
+ ]
1821
+ }
1822
+ )
1823
+ ] })
1824
+ ] });
3697
1825
  };
3698
-
3699
- // src/ai-plugin/common/globals.ts
3700
- var import_react3 = require("@hawtio/react");
3701
- var pluginName2 = "hawtio-ai";
3702
- var pluginTitle2 = "AI";
3703
- var log2 = import_react3.Logger.get(pluginName2);
3704
1826
 
3705
1827
  // src/ai-plugin/common/index.ts
3706
- var order = 40;
1828
+ init_globals2();
1829
+ var order2 = 40;
3707
1830
  var aiCommon = () => {
3708
- import_react4.preferencesRegistry.add(pluginName2, pluginTitle2, AiPreferences, order);
1831
+ import_react11.preferencesRegistry.add(pluginName2, pluginTitle2, AiPreferences, order2);
3709
1832
  };
3710
1833
 
3711
1834
  // src/ai-plugin/jmx-ai/index.ts
3712
- var import_react16 = require("@hawtio/react");
3713
- init_globals();
1835
+ var import_react22 = require("@hawtio/react");
1836
+ init_globals3();
3714
1837
 
3715
1838
  // src/ai-plugin/jmx-ai/help.md
3716
1839
  var help_default = "# JMX AI - Hawtio AI Plugin\n\nThis view is provided by the Hawtio AI plugin.\n\nIt extends the standard [JMX](./jmx) and adds AI features such as MBean diagnostics to it.\n";
3717
1840
 
3718
1841
  // src/ai-plugin/jmx-ai/index.ts
3719
- var order2 = 41;
3720
- var jmxAi = () => {
3721
- log.info("Loading", pluginName);
3722
- import_react16.hawtio.addDeferredPlugin(pluginName, async () => {
3723
- return Promise.resolve().then(() => (init_ui(), ui_exports)).then(({ Jmx: Jmx2 }) => {
1842
+ var order3 = 41;
1843
+ var aiJmx = () => {
1844
+ log3.info("Loading", pluginName3);
1845
+ import_react22.hawtio.addDeferredPlugin(pluginName3, async () => {
1846
+ return Promise.resolve().then(() => (init_ui2(), ui_exports2)).then(({ Jmx: Jmx2 }) => {
3724
1847
  return {
3725
- id: pluginName,
3726
- title: pluginTitle,
3727
- path: pluginPath,
1848
+ id: pluginName3,
1849
+ title: pluginTitle3,
1850
+ path: pluginPath2,
1851
+ order: order3,
3728
1852
  component: Jmx2,
3729
1853
  knownQueryParams: ["nid"],
3730
- isActive: async () => import_react16.workspace.hasMBeans()
1854
+ isActive: async () => import_react22.workspace.hasMBeans()
3731
1855
  };
3732
1856
  });
3733
1857
  });
3734
- import_react16.helpRegistry.add(pluginName, pluginTitle, help_default, order2);
1858
+ import_react22.helpRegistry.add(pluginName3, pluginTitle3, help_default, order3);
3735
1859
  };
3736
1860
 
3737
1861
  // src/ai-plugin/index.ts
3738
1862
  var plugin = () => {
3739
1863
  aiCommon();
3740
- jmxAi();
1864
+ aiJmx();
1865
+ aiChat();
3741
1866
  };
3742
- import_react17.configManager.addProductInfo("Hawtio AI Plugin", "0.2.2");
1867
+ import_react23.configManager.addProductInfo("Hawtio AI Plugin", "0.3.0");
3743
1868
  // Annotate the CommonJS export names for ESM import in node:
3744
1869
  0 && (module.exports = {
3745
1870
  plugin
3746
1871
  });
3747
- /*! Bundled license information:
3748
-
3749
- react-is/cjs/react-is.production.min.js:
3750
- (** @license React v16.13.1
3751
- * react-is.production.min.js
3752
- *
3753
- * Copyright (c) Facebook, Inc. and its affiliates.
3754
- *
3755
- * This source code is licensed under the MIT license found in the
3756
- * LICENSE file in the root directory of this source tree.
3757
- *)
3758
-
3759
- react-is/cjs/react-is.development.js:
3760
- (** @license React v16.13.1
3761
- * react-is.development.js
3762
- *
3763
- * Copyright (c) Facebook, Inc. and its affiliates.
3764
- *
3765
- * This source code is licensed under the MIT license found in the
3766
- * LICENSE file in the root directory of this source tree.
3767
- *)
3768
-
3769
- object-assign/index.js:
3770
- (*
3771
- object-assign
3772
- (c) Sindre Sorhus
3773
- @license MIT
3774
- *)
3775
- */
3776
1872
  //# sourceMappingURL=index.js.map