@hawtio/ai-plugin 0.3.0 → 0.3.1

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/CHANGELOG.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
4
4
 
5
+ ## [0.3.1](///compare/v0.3.0...v0.3.1) (2026-09-28)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * Anthropic models fail due to unsupported temperature parameter 3203da1
11
+ * model not saved when switching provider in AI preferences e6d8d17
12
+
5
13
  ## [0.3.0](///compare/v0.2.2...v0.3.0) (2026-09-24)
6
14
 
7
15
 
package/dist/index.js CHANGED
@@ -413,7 +413,6 @@ var init_ai_service = __esm({
413
413
  this.llm = new import_anthropic.ChatAnthropic({
414
414
  model: this.model.id,
415
415
  apiKey: token,
416
- temperature: 0,
417
416
  streaming: false
418
417
  });
419
418
  break;
@@ -1699,7 +1698,9 @@ var ModelForm = ({ options, setOptions }) => {
1699
1698
  const [passwordHidden, setPasswordHidden] = (0, import_react10.useState)(true);
1700
1699
  const updateProvider = (provider2) => {
1701
1700
  setProvider(provider2);
1702
- setModels(MODELS.filter((m) => m.provider === provider2));
1701
+ const models2 = MODELS.filter((m) => m.provider === provider2);
1702
+ setModels(models2);
1703
+ updateModel(models2[0].id);
1703
1704
  };
1704
1705
  const updateModel = (updated) => {
1705
1706
  const model = MODELS.find((m) => m.id === updated);
@@ -1864,7 +1865,7 @@ var plugin = () => {
1864
1865
  aiJmx();
1865
1866
  aiChat();
1866
1867
  };
1867
- import_react23.configManager.addProductInfo("Hawtio AI Plugin", "0.3.0");
1868
+ import_react23.configManager.addProductInfo("Hawtio AI Plugin", "0.3.1");
1868
1869
  // Annotate the CommonJS export names for ESM import in node:
1869
1870
  0 && (module.exports = {
1870
1871
  plugin
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ai-plugin/chat/globals.ts","../src/ai-plugin/chat/Chat.css","../src/ai-plugin/common/ai-model.ts","../src/ai-plugin/common/ai-preferences-service.ts","../src/ai-plugin/common/globals.ts","../src/ai-plugin/common/workspace.ts","../src/ai-plugin/common/tools.ts","../src/ai-plugin/common/ai-service.ts","../src/ai-plugin/chat/model.ts","../src/ai-plugin/chat/context.ts","../src/ai-plugin/chat/ThinkInfo.tsx","../src/ai-plugin/chat/ToolCallsInfo.tsx","../src/ai-plugin/chat/ToolCallsApprove.tsx","../src/ai-plugin/chat/ChatbotPanel.tsx","../src/ai-plugin/chat/Chat.tsx","../src/ai-plugin/chat/ui.ts","../src/ai-plugin/jmx-ai/globals.ts","../src/ai-plugin/jmx-ai/context.ts","../src/ai-plugin/jmx-ai/Jmx.css","../src/ai-plugin/jmx-ai/JmxContent.css","../src/ai-plugin/jmx-ai/jmx-ai-service.ts","../src/ai-plugin/jmx-ai/util.ts","../src/ai-plugin/jmx-ai/attributes/attribute-service.ts","../src/ai-plugin/jmx-ai/attributes/Attributes.tsx","../src/ai-plugin/jmx-ai/attributes/index.ts","../src/ai-plugin/jmx-ai/JmxContent.tsx","../src/ai-plugin/jmx-ai/JmxTreeView.css","../src/ai-plugin/jmx-ai/JmxTreeView.tsx","../src/ai-plugin/jmx-ai/Jmx.tsx","../src/ai-plugin/jmx-ai/ui.ts","../src/ai-plugin/index.ts","../src/ai-plugin/chat/index.ts","../src/ai-plugin/common/index.ts","../src/ai-plugin/common/AiPreferences.tsx","../src/ai-plugin/jmx-ai/index.ts","../src/ai-plugin/jmx-ai/help.md"],"sourcesContent":["import { Logger } from '@hawtio/react'\n\nexport const pluginName = 'hawtio-ai-chat'\nexport const pluginTitle = 'AI Chat'\nexport const pluginPath = '/ai-chat'\n\nexport const log = Logger.get(pluginName)\n",".pf-v6-c-page__main-container:has(#chat-content) {\n height: 100%;\n margin: 0;\n}\n","export const PROVIDERS = ['openai', 'anthropic', 'google-genai', 'ollama'] as const\nexport type AiProvider = (typeof PROVIDERS)[number]\n\nexport type AiModel = {\n id: string\n name: string\n tool: boolean\n provider: AiProvider\n}\n\nexport const MODELS: AiModel[] = [\n // OpenAI models\n { id: 'gpt-5.5', name: 'GPT-5.5', tool: true, provider: 'openai' },\n { id: 'gpt-5.4', name: 'GPT-5.4', tool: true, provider: 'openai' },\n { id: 'gpt-5.4-mini', name: 'GPT-5.4 mini', tool: true, provider: 'openai' },\n\n // Anthropic Claude models\n { id: 'claude-opus-4-7', name: 'Claude Opus 4.7', tool: true, provider: 'anthropic' },\n { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', tool: true, provider: 'anthropic' },\n { id: 'claude-haiku-4-5', name: 'Claude Haiku 4.5', tool: true, provider: 'anthropic' },\n\n // Google Gemini models\n { id: 'gemini-3.5-flash', name: 'Gemini 3.5 Flash', tool: true, provider: 'google-genai' },\n { id: 'gemini-3.1-flash-lite', name: 'Gemini 3.1 Flash-Lite', tool: true, provider: 'google-genai' },\n { id: 'gemini-3.1-pro', name: 'Gemini 3.1 Pro', tool: true, provider: 'google-genai' },\n\n // Ollama models\n { id: 'granite4.1:3b', name: 'Granite 4.1 3B', tool: true, provider: 'ollama' },\n { id: 'llama3:latest', name: 'Llama 3', tool: false, provider: 'ollama' },\n { id: 'llama3.2:latest', name: 'Llama 3.2', tool: true, provider: 'ollama' },\n { id: 'gemma4:e4b', name: 'Gemma 4 4B', tool: true, provider: 'ollama' },\n { id: 'gemma4:e4b-mlx', name: 'Gemma 4 4B MLX', tool: true, provider: 'ollama' },\n { id: 'phi4:latest', name: 'Phi 4', tool: false, provider: 'ollama' },\n { id: 'phi3.5:latest', name: 'Phi 3.5', tool: false, provider: 'ollama' },\n { id: 'qwen3.5:4b', name: 'Qwen 3.5 4B', tool: true, provider: 'ollama' },\n { id: 'qwen3.5:4b-mlx', name: 'Qwen 3.5 4B MLX', tool: true, provider: 'ollama' },\n { id: 'qwen3.5:latest', name: 'Qwen 3.5', tool: true, provider: 'ollama' },\n] as const\n","import { AiModel, MODELS } from './ai-model'\nimport { aiService } from './ai-service'\n\nexport const STORAGE_KEY_PREFERENCES = 'ai.preferences'\n\n/**\n * Per-tool auto-approval map.\n * Key: tool name (e.g. 'listMBeans'), Value: true = auto-approve without prompting.\n */\nexport type ToolPermissions = Record<string, boolean>\n\nexport type AiOptions = {\n model: AiModel\n token?: string\n toolPermissions?: ToolPermissions\n /**\n * Maximum number of consecutive auto-approved tool-call steps per chat turn.\n * Prevents runaway execution when the LLM repeatedly emits approved tool calls.\n */\n maxAutoToolSteps?: number\n}\n\n/**\n * Workspace-cache-only tools are auto-approved by default (no remote side effects).\n * Jolokia-backed tools default to OFF so the user must explicitly approve them.\n */\nexport const DEFAULT_TOOL_PERMISSIONS: ToolPermissions = {\n listMBeans: true,\n getMBeanInfo: true,\n searchMBeans: true,\n readMBeanAttribute: false,\n writeMBeanAttribute: false,\n executeMBeanOperation: false,\n}\n\nexport const DEFAULT_MAX_AUTO_TOOL_STEPS = 10\n\nexport const DEFAULT_OPTIONS: AiOptions = {\n model: MODELS[0]!,\n toolPermissions: DEFAULT_TOOL_PERMISSIONS,\n maxAutoToolSteps: DEFAULT_MAX_AUTO_TOOL_STEPS,\n} as const\n\nexport interface IAiPreferencesService {\n loadOptions(): AiOptions\n saveOptions(options: Partial<AiOptions>): void\n}\n\nclass AiPreferencesService implements IAiPreferencesService {\n loadOptions(): AiOptions {\n const item = localStorage.getItem(STORAGE_KEY_PREFERENCES)\n const savedOptions = item ? JSON.parse(item) : {}\n return { ...DEFAULT_OPTIONS, ...savedOptions }\n }\n\n saveOptions(options: Partial<AiOptions>) {\n const updated = { ...this.loadOptions(), ...options }\n localStorage.setItem(STORAGE_KEY_PREFERENCES, JSON.stringify(updated))\n if (options.model) {\n aiService.reset(options.model)\n }\n }\n}\n\nexport const aiPreferencesService = new AiPreferencesService()\n","import { Logger } from '@hawtio/react'\n\nexport const pluginName = 'hawtio-ai'\nexport const pluginTitle = 'AI'\n\nexport const log = Logger.get(pluginName)\n","import { IJolokiaService, IWorkspace, OptimisedMBeanInfo, jolokiaService, workspace } from '@hawtio/react'\nimport { log } from './globals'\n\nexport interface IWorkspaceExtension {\n /** List all ObjectNames available in the workspace cache. */\n listMBeans(): Promise<string[]>\n\n /**\n * Return the OptimisedMBeanInfo for a specific MBean from the workspace cache.\n * Returns null if the MBean is not found in the cache.\n */\n getMBeanInfo(objectName: string): Promise<OptimisedMBeanInfo | null>\n\n /** Read the current value of an MBean attribute via Jolokia. */\n readMBeanAttribute(objectName: string, attribute: string): Promise<unknown>\n\n /** Write a value to a writable MBean attribute via Jolokia. */\n writeMBeanAttribute(objectName: string, attribute: string, value: unknown): Promise<unknown>\n\n /** Execute an MBean operation via Jolokia. */\n executeMBeanOperation(objectName: string, operation: string, args?: unknown[]): Promise<unknown>\n}\n\n/**\n * Extends the Hawtio workspace with MBean query and Jolokia operation methods\n * for use by AI tools. No LangChain dependency — pure Hawtio logic only.\n *\n * Read-only methods (workspace cache):\n * - listMBeans()\n * - getMBeanInfo(objectName)\n *\n * Jolokia methods (live server calls):\n * - readMBeanAttribute(objectName, attribute)\n * - writeMBeanAttribute(objectName, attribute, value)\n * - executeMBeanOperation(objectName, operation, args?)\n */\nclass WorkspaceExtension implements IWorkspaceExtension {\n constructor(\n private readonly workspace: IWorkspace,\n private readonly jolokiaService: IJolokiaService,\n ) {}\n\n async listMBeans(): Promise<string[]> {\n log.debug('workspace - listMBeans called')\n const tree = await this.workspace.getTree()\n const flat = tree.flatten()\n const result = Object.keys(flat).sort()\n log.debug('workspace - listMBeans result count:', result.length)\n return result\n }\n\n async getMBeanInfo(objectName: string): Promise<OptimisedMBeanInfo | null> {\n log.debug('workspace - getMBeanInfo called:', objectName)\n const tree = await this.workspace.getTree()\n const flat = tree.flatten()\n const mbeanInfo = flat[objectName]?.mbean ?? null\n if (!mbeanInfo) {\n log.debug('workspace - getMBeanInfo: not found:', objectName)\n }\n return mbeanInfo\n }\n\n async readMBeanAttribute(objectName: string, attribute: string): Promise<unknown> {\n log.debug('workspace - readMBeanAttribute called:', objectName, attribute)\n return this.jolokiaService.readAttribute(objectName, attribute)\n }\n\n async writeMBeanAttribute(objectName: string, attribute: string, value: unknown): Promise<unknown> {\n log.debug('workspace - writeMBeanAttribute called:', objectName, attribute, value)\n return this.jolokiaService.writeAttribute(objectName, attribute, value)\n }\n\n async executeMBeanOperation(objectName: string, operation: string, args?: unknown[]): Promise<unknown> {\n log.debug('workspace - executeMBeanOperation called:', objectName, operation, args)\n return this.jolokiaService.execute(objectName, operation, args)\n }\n}\n\nexport const workspaceExtension: IWorkspaceExtension = new WorkspaceExtension(workspace, jolokiaService)\n","import { MBeanNode, workspace } from '@hawtio/react'\nimport { DynamicStructuredTool } from '@langchain/core/tools'\nimport { z } from 'zod'\nimport { log } from './globals'\nimport { workspaceExtension } from './workspace'\n\nfunction listMBeansTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'listMBeans',\n description: `\n List all MBean ObjectNames available in the Hawtio workspace cache.\n Use this to discover what MBeans are present before querying details.\n `,\n schema: z.object({}),\n func: async (): Promise<string> => {\n log.debug('tools - listMBeans called')\n const result = await workspaceExtension.listMBeans()\n return JSON.stringify(result)\n },\n })\n}\n\nfunction getMBeanInfoTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'getMBeanInfo',\n description: `\n Return the attribute schema (type, description, read/write flag) and operation definitions\n (arguments, return type, description) for a specific MBean.\n Call this before readMBeanAttribute or executeMBeanOperation to inspect available fields.\n `,\n schema: z.object({\n objectName: z.string().describe(\"JMX ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n }),\n func: async ({ objectName }): Promise<string> => {\n log.debug('tools - getMBeanInfo called:', objectName)\n const info = await workspaceExtension.getMBeanInfo(objectName)\n if (!info) {\n return JSON.stringify({ error: `MBean not found: ${objectName}` })\n }\n return JSON.stringify({ objectName, attr: info.attr, op: info.op })\n },\n })\n}\n\nfunction searchMBeansTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'searchMBeans',\n description: `\n Search MBeans by JMX domain and property key/value pairs.\n Returns a list of matching ObjectNames.\n Use this to narrow down MBeans by type or name, e.g. domain='java.lang', properties='{\"type\":\"Memory\"}'.\n `,\n schema: z.object({\n domain: z.string().describe(\"JMX domain to search in, e.g. 'java.lang'\"),\n properties: z\n .string()\n .describe('JSON string of JMX property key/value pairs to match, e.g. \\'{\"type\":\"Memory\"}\\''),\n }),\n func: async ({ domain, properties }): Promise<string> => {\n log.debug('tools - searchMBeans called:', domain, properties)\n let parsed: unknown\n try {\n parsed = JSON.parse(properties)\n } catch {\n return JSON.stringify({ error: `Invalid JSON for properties: ${properties}` })\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return JSON.stringify({ error: `properties must be a JSON object, got: ${properties}` })\n }\n const nodes: MBeanNode[] = await workspace.findMBeans(domain, parsed as Record<string, unknown>)\n const result = nodes.map((n: MBeanNode) => n.objectName).filter((s): s is string => s !== undefined)\n log.debug('tools - searchMBeans result count:', result.length)\n return JSON.stringify(result)\n },\n })\n}\n\nfunction readMBeanAttributeTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'readMBeanAttribute',\n description: `\n Read the current value of an MBean attribute via Jolokia.\n This is a read-only operation with no side effects.\n Use getMBeanInfo first to confirm the attribute name and type.\n `,\n schema: z.object({\n objectName: z.string().describe(\"ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n attribute: z.string().describe(\"Name of the attribute to read, e.g. 'HeapMemoryUsage'\"),\n }),\n func: async ({ objectName, attribute }): Promise<string> => {\n log.debug('tools - readMBeanAttribute called:', objectName, attribute)\n try {\n const value = await workspaceExtension.readMBeanAttribute(objectName, attribute)\n return JSON.stringify({ objectName, attribute, value })\n } catch (e) {\n return JSON.stringify({ error: String(e) })\n }\n },\n })\n}\n\nfunction writeMBeanAttributeTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'writeMBeanAttribute',\n description: `\n Write a value to a writable MBean attribute via Jolokia.\n Verify rw=true with getMBeanInfo before calling this tool.\n `,\n schema: z.object({\n objectName: z.string().describe(\"ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n attribute: z.string().describe('Name of the attribute to write'),\n value: z.string().describe('JSON-encoded value to set, e.g. \"42\" or \"true\" or \"\\\\\"hello\\\\\"\"'),\n }),\n func: async ({ objectName, attribute, value }): Promise<string> => {\n log.debug('tools - writeMBeanAttribute called:', objectName, attribute, value)\n let parsed: unknown\n try {\n parsed = JSON.parse(value)\n } catch {\n parsed = value\n }\n try {\n const result = await workspaceExtension.writeMBeanAttribute(objectName, attribute, parsed)\n return JSON.stringify({ objectName, attribute, result })\n } catch (e) {\n return JSON.stringify({ error: String(e) })\n }\n },\n })\n}\n\nfunction executeMBeanOperationTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'executeMBeanOperation',\n description: `\n Execute an MBean operation via Jolokia.\n Use getMBeanInfo to verify the operation signature before calling.\n For overloaded operations include the signature, e.g. 'gc()'.\n `,\n schema: z.object({\n objectName: z.string().describe(\"ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n operation: z.string().describe(\"Operation name to invoke, e.g. 'gc' or 'gc()'\"),\n args: z\n .array(z.string())\n .optional()\n .describe('JSON-encoded arguments to pass to the operation, e.g. [\"value1\", \"42\"]'),\n }),\n func: async ({ objectName, operation, args }): Promise<string> => {\n log.debug('tools - executeMBeanOperation called:', objectName, operation, args)\n const parsedArgs = args?.map((a: string) => {\n try {\n return JSON.parse(a)\n } catch {\n return a\n }\n })\n try {\n const result = await workspaceExtension.executeMBeanOperation(objectName, operation, parsedArgs)\n return JSON.stringify({ objectName, operation, result })\n } catch (e) {\n return JSON.stringify({ error: String(e) })\n }\n },\n })\n}\n\n/** Returns all the workspace tools available in Hawtio AI. */\nexport function getWorkspaceTools(): DynamicStructuredTool[] {\n return [\n listMBeansTool(),\n getMBeanInfoTool(),\n searchMBeansTool(),\n readMBeanAttributeTool(),\n writeMBeanAttributeTool(),\n executeMBeanOperationTool(),\n ]\n}\n\n/** Metadata for all workspace tools, derived from tool definitions for the AI Preferences UI. */\nexport const WORKSPACE_TOOLS_META = getWorkspaceTools().map(({ name, description }) => ({ name, description }))\n","import { ChatAnthropic } from '@langchain/anthropic'\nimport { BaseLanguageModelInput } from '@langchain/core/language_models/base'\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from '@langchain/core/messages'\nimport { ToolCall } from '@langchain/core/messages/tool'\nimport { Runnable } from '@langchain/core/runnables'\nimport { DynamicStructuredTool } from '@langchain/core/tools'\nimport { ChatGoogleGenerativeAI } from '@langchain/google-genai'\nimport { ChatOllama } from '@langchain/ollama'\nimport { ChatOpenAI } from '@langchain/openai'\nimport { MessageExtraContent, MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport botAvatar from '@patternfly/chatbot/patternfly-docs/content/extensions/chatbot/examples/Messages/patternfly_avatar.jpg'\nimport userAvatar from '@patternfly/react-core/dist/styles/assets/images/img_avatar-light.svg'\nimport { ComponentType, createElement } from 'react'\nimport { AiModel } from './ai-model'\nimport { aiPreferencesService } from './ai-preferences-service'\nimport { log } from './globals'\nimport { getWorkspaceTools } from './tools'\n\nconst BOT_NAME = 'Hawtio AI'\n\nconst TOOLS: DynamicStructuredTool[] = getWorkspaceTools()\nconst TOOLS_BY_NAME: Record<string, DynamicStructuredTool> = TOOLS.reduce(\n (acc, tool) => {\n acc[tool.name] = tool\n return acc\n },\n {} as Record<string, DynamicStructuredTool>,\n)\n\nexport type MessageWithThink = {\n content: string\n think?: string\n}\n\nexport type LLM = ChatOpenAI | ChatAnthropic | ChatGoogleGenerativeAI | ChatOllama\n\nexport interface IAiService {\n reset(model: AiModel): void\n getModel(): AiModel | undefined\n newChat(\n dialogId: string,\n initialMessage: { message: string; system?: string },\n onMessage?: (answer: AIMessage) => void,\n ): Promise<AIMessage | string>\n chat(dialogId: string, message: string, onMessage?: (answer: AIMessage) => void): Promise<AIMessage | string>\n invokeTools(\n dialogId: string,\n toolCalls: ToolCall[],\n onMessage?: (answer: AIMessage) => void,\n step?: number,\n ): Promise<AIMessage | string>\n hasToolCalls(answer: AIMessage | string): answer is AIMessage\n rejectTools(dialogId: string, toolCalls: ToolCall[]): void\n createUserMessage(name: string, content: string): MessageProps\n createLoadingBotMessage(): MessageProps\n createBotMessage(content: string, extraContent?: MessageExtraContent): MessageProps\n toBotMessage(\n answer: AIMessage | string,\n autoApproved: boolean,\n ThinkInfo: ComponentType<{ think: string }>,\n ToolCallsInfo: ComponentType<{ call: ToolCall; index: number }>,\n ToolCallsApprove: ComponentType<{ toolCalls: ToolCall[]; messageId: string }>,\n ): MessageProps\n}\n\nclass AiService implements IAiService {\n private model?: AiModel\n private llm?: LLM\n private llmWithTools?: Runnable<BaseLanguageModelInput, AIMessageChunk>\n private memory: Record<string, BaseMessage[]> = {}\n\n private appendToolMessages(messages: BaseMessage[], toolCalls: ToolCall[], content: string): void {\n for (const call of toolCalls) {\n messages.push(new ToolMessage({ tool_call_id: call.id ?? call.name, content }))\n }\n }\n\n reset(model: AiModel): void {\n if (this.model && this.model.id === model.id && this.llm && (!model.tool || this.llmWithTools)) {\n return\n }\n log.info('AI model to use:', model.id)\n // Reset the current memory\n this.memory = {}\n const { token } = aiPreferencesService.loadOptions()\n this.model = model\n try {\n switch (this.model.provider) {\n case 'openai':\n this.llm = new ChatOpenAI({\n model: this.model.id,\n apiKey: token,\n streaming: false,\n })\n break\n case 'anthropic':\n this.llm = new ChatAnthropic({\n model: this.model.id,\n apiKey: token,\n temperature: 0,\n streaming: false,\n })\n break\n case 'google-genai':\n this.llm = new ChatGoogleGenerativeAI({\n model: this.model.id,\n apiKey: token,\n temperature: 0,\n disableStreaming: true,\n })\n break\n case 'ollama':\n default:\n this.llm = new ChatOllama({\n model: this.model.id,\n streaming: false,\n })\n }\n } catch (error) {\n // Mostly token is missing/invalid\n log.warn('Error initialising AI model:', error)\n this.llm = undefined\n }\n this.llmWithTools = undefined\n if (TOOLS.length !== 0 && this.model.tool) {\n this.llmWithTools = this.llm?.bindTools(TOOLS)\n }\n }\n\n private getLlm(): LLM | Runnable<BaseLanguageModelInput, AIMessageChunk> | undefined {\n if (!this.model || !this.llm) {\n const { model } = aiPreferencesService.loadOptions()\n this.reset(model)\n }\n return this.llmWithTools ?? this.llm\n }\n\n getModel(): AiModel | undefined {\n this.getLlm()\n return this.model\n }\n\n private async invoke(messages: BaseMessage[]): Promise<AIMessage | string> {\n // Lazy init model and llm\n const llm = this.getLlm()\n log.debug('Chatting with', this.model?.id, ':', messages)\n try {\n let answer: AIMessageChunk\n if (!llm) {\n throw new Error('AI model not configured')\n }\n answer = await llm.invoke(messages)\n\n if (answer.tool_calls && answer.tool_calls.length > 0) {\n log.debug('🛠️ calls:', answer.tool_calls)\n }\n log.debug('Answer:', answer)\n return answer\n } catch (error) {\n log.error('Error while chatting:', error)\n return String(error)\n }\n }\n\n newChat(\n dialogId: string,\n initialMessage: { message: string; system?: string },\n onMessage?: (answer: AIMessage) => void,\n ): Promise<AIMessage | string> {\n const { message, system } = initialMessage\n if (system) {\n this.memory[dialogId] = [new SystemMessage(system)]\n } else {\n this.memory[dialogId] = []\n }\n return this.chat(dialogId, message, onMessage)\n }\n\n hasToolCalls(answer: AIMessage | string): answer is AIMessage {\n return typeof answer !== 'string' && (answer.tool_calls?.length ?? 0) > 0\n }\n\n async chat(dialogId: string, message: string, onMessage?: (answer: AIMessage) => void): Promise<AIMessage | string> {\n let messages = this.memory[dialogId]\n if (!messages) {\n messages = []\n this.memory[dialogId] = messages\n }\n messages.push(new HumanMessage(message))\n const answer = await this.invoke(messages)\n if (typeof answer !== 'string') {\n messages.push(answer)\n }\n log.debug('Current messages:', messages)\n\n // If the LLM requests auto-approved tool calls, delegate to invokeTools which\n // handles the full auto-approve loop with a step limit.\n if (this.hasToolCalls(answer)) {\n const { toolPermissions } = aiPreferencesService.loadOptions()\n if (answer.tool_calls!.every(call => toolPermissions?.[call.name] === true)) {\n onMessage?.(answer)\n return this.invokeTools(dialogId, answer.tool_calls!, onMessage)\n }\n }\n\n return answer\n }\n\n /**\n * Executes the given tool calls and invokes the LLM with the results.\n * If the LLM responds with further tool calls that are all auto-approved,\n * this method recurses (up to {@link maxAutoToolSteps} times) to continue\n * the chain without interruption. Tool calls that are not auto-approved are\n * returned as-is so the caller can decide to approve or reject them.\n *\n * @param step - Current recursion depth; used to enforce the step limit.\n */\n async invokeTools(\n dialogId: string,\n toolCalls: ToolCall[],\n onMessage?: (answer: AIMessage) => void,\n step = 0,\n ): Promise<AIMessage | string> {\n if (!this.llmWithTools) {\n return 'Tool invocation not supported'\n }\n\n let messages = this.memory[dialogId]\n if (!messages) {\n messages = []\n this.memory[dialogId] = messages\n }\n\n const { toolPermissions, maxAutoToolSteps } = aiPreferencesService.loadOptions()\n if (step >= maxAutoToolSteps!) {\n const limitMessage = `Automatic tool-call step limit reached after ${maxAutoToolSteps} steps.`\n this.appendToolMessages(messages, toolCalls, limitMessage)\n log.warn(`Auto-tool execution stopped after ${maxAutoToolSteps} steps to prevent runaway execution.`)\n return `Stopped after ${maxAutoToolSteps} automatic tool-call steps. You can increase the limit in Preferences.`\n }\n\n try {\n for (const call of toolCalls) {\n log.debug('🛠️ Call:', call.name, JSON.stringify(call.args))\n const selectedTool = TOOLS_BY_NAME[call.name]\n const toolAnswer = await selectedTool?.invoke(call)\n if (toolAnswer) {\n log.debug('🛠️ ' + call.name + ':', toolAnswer)\n messages.push(toolAnswer)\n }\n }\n const answer = await this.llmWithTools.invoke(messages)\n if (answer) {\n messages.push(answer)\n }\n log.debug('Messages>>', messages)\n\n // If the LLM requests more auto-approved tool calls, recurse with incremented step counter\n if (this.hasToolCalls(answer) && answer.tool_calls!.every(call => toolPermissions?.[call.name] === true)) {\n onMessage?.(answer)\n return this.invokeTools(dialogId, answer.tool_calls!, onMessage, step + 1)\n }\n\n return answer\n } catch (error) {\n log.error('Error while invoking tools:', error)\n return String(error)\n }\n }\n\n rejectTools(dialogId: string, toolCalls: ToolCall[]): void {\n const messages = this.memory[dialogId]\n if (!messages) return\n this.appendToolMessages(messages, toolCalls, 'User rejected')\n log.debug(\n 'rejectTools - added rejection ToolMessages for:',\n toolCalls.map(c => c.name),\n )\n }\n\n private generateId(): string {\n return crypto.randomUUID()\n }\n\n createUserMessage(name: string, content: string): MessageProps {\n const id = this.generateId()\n return {\n id,\n role: 'user',\n content,\n name,\n avatar: userAvatar,\n timestamp: new Date().toLocaleString(),\n }\n }\n\n createLoadingBotMessage(): MessageProps {\n const id = this.generateId()\n return {\n id,\n role: 'bot',\n name: BOT_NAME,\n avatar: botAvatar,\n avatarProps: { style: { fontSize: '90%' } },\n content: 'API response goes here',\n isLoading: true,\n }\n }\n\n createBotMessage(content: string, extraContent?: MessageExtraContent): MessageProps {\n const id = this.generateId()\n return {\n id,\n role: 'bot',\n name: BOT_NAME,\n avatar: botAvatar,\n avatarProps: { style: { fontSize: '90%' } },\n content,\n extraContent,\n isLoading: false,\n timestamp: new Date().toLocaleString(),\n }\n }\n\n private extractThink(message: AIMessage): MessageWithThink {\n const content = message.content as string\n let think: string | undefined\n if (message.additional_kwargs?.reasoning_content) {\n think = message.additional_kwargs?.reasoning_content as string | undefined\n }\n return { content, think }\n }\n\n toBotMessage(\n answer: AIMessage | string,\n autoApproved: boolean,\n ThinkInfo: ComponentType<{ think: string }>,\n ToolCallsInfo: ComponentType<{ call: ToolCall; index: number }>,\n ToolCallsApprove: ComponentType<{ toolCalls: ToolCall[]; messageId: string }>,\n ): MessageProps {\n if (typeof answer === 'string') {\n // Error\n return this.createBotMessage(`Error: ${answer}`)\n }\n\n if (!answer.tool_calls || answer.tool_calls.length === 0) {\n // No tool calls — normal text response\n const { content, think } = this.extractThink(answer)\n const extraContent = think ? { beforeMainContent: createElement(ThinkInfo, { think }) } : undefined\n return this.createBotMessage(content, extraContent)\n }\n\n // Tool calls — show which tools are being used\n const toolCalls = answer.tool_calls\n const isMultiple = toolCalls.length > 1\n const toolNames = toolCalls\n .map(call => `**${call.name}**`)\n .filter((name, index, self) => self.indexOf(name) === index)\n .join(', ')\n const beforeMainContent = toolCalls.map((call, index) => createElement(ToolCallsInfo, { key: index, call, index }))\n\n if (autoApproved) {\n const content = `Auto-approved ${toolCalls.length} tool ${isMultiple ? 'calls' : 'call'}: ${toolNames}`\n return this.createBotMessage(content, { beforeMainContent })\n }\n\n const content = `${BOT_NAME} wants to use ${isMultiple ? 'tools' : 'a tool'}: ${toolNames}`\n const botMessage = this.createBotMessage(content)\n botMessage.extraContent = {\n beforeMainContent,\n afterMainContent: createElement(ToolCallsApprove, { toolCalls, messageId: botMessage.id! }),\n }\n return botMessage\n }\n}\n\nexport const aiService = new AiService()\n","import { Conversation } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\n\nexport class ChatbotDialog {\n public readonly id: string\n\n constructor(\n public messages: MessageProps[],\n private summary?: string,\n ) {\n this.id = messages[0]?.id ?? ''\n }\n\n setMessages(messages: MessageProps[]) {\n if (messages[0]?.id !== this.id) {\n throw new Error('Not the same dialog')\n }\n this.messages = [...messages]\n }\n\n createConversation(): Conversation {\n const text = this.summary ?? (this.messages[0]?.content ?? '').substring(0, 20)\n return { id: this.id, text }\n }\n}\n","import { Conversation } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport { createContext, Dispatch, useState } from 'react'\nimport { log } from './globals'\nimport { ChatbotDialog } from './model'\n\n/**\n * Custom React hook for managing AI Chatbot state and conversation history.\n *\n * Provides state and controls for:\n * - Active messages and multi-dialog conversation history\n * - Assistive device announcements (accessibility)\n * - Drawer open/close visibility and send button state\n */\nexport function useChatbot(): ChatbotContext {\n const [messages, setMessages] = useState<MessageProps[]>([])\n const [dialogs, setDialogs] = useState<ChatbotDialog[]>([])\n const [conversations, setConversations] = useState<Conversation[]>([])\n const [announcement, setAnnouncement] = useState('')\n const [isChatbotOpen, setIsChatbotOpen] = useState(false)\n const [isSendButtonDisabled, setIsSendButtonDisabled] = useState(false)\n\n const updateConversations = (messages: MessageProps[], summary?: string) => {\n const dialogId = messages[0]?.id\n if (!dialogId) {\n return\n }\n setMessages(messages)\n let dialog = dialogs.find(d => d.id === dialogId)\n if (dialog) {\n dialog.setMessages(messages)\n } else {\n dialog = new ChatbotDialog(messages, summary)\n dialogs.push(dialog)\n }\n setDialogs([...dialogs])\n log.debug('Updated dialogs:', dialogs)\n\n if (!conversations.some(c => c.id === dialogId)) {\n const conversation = dialog.createConversation()\n conversations.push(conversation)\n setConversations([...conversations])\n log.debug('Updated conversations:', conversations)\n }\n }\n\n return {\n messages,\n setMessages,\n dialogs,\n setDialogs,\n conversations,\n setConversations,\n announcement,\n setAnnouncement,\n isChatbotOpen,\n setIsChatbotOpen,\n isSendButtonDisabled,\n setIsSendButtonDisabled,\n updateConversations,\n }\n}\n\nexport type ChatbotContext = {\n messages: MessageProps[]\n setMessages: Dispatch<React.SetStateAction<MessageProps[]>>\n dialogs: ChatbotDialog[]\n setDialogs: Dispatch<React.SetStateAction<ChatbotDialog[]>>\n conversations: Conversation[]\n setConversations: Dispatch<React.SetStateAction<Conversation[]>>\n announcement: string\n setAnnouncement: Dispatch<React.SetStateAction<string>>\n isChatbotOpen: boolean\n setIsChatbotOpen: (value: boolean) => void\n isSendButtonDisabled: boolean\n setIsSendButtonDisabled: (value: boolean) => void\n updateConversations: (messages: MessageProps[], summary?: string) => void\n}\n\nexport const ChatbotContext = createContext<ChatbotContext>({\n messages: [],\n setMessages: () => {\n /* no-op */\n },\n dialogs: [],\n setDialogs: () => {\n /* no-op */\n },\n conversations: [],\n setConversations: () => {\n /* no-op */\n },\n announcement: '',\n setAnnouncement: () => {\n /* no-op */\n },\n isChatbotOpen: false,\n setIsChatbotOpen: () => {\n /* no-op */\n },\n isSendButtonDisabled: false,\n setIsSendButtonDisabled: () => {\n /* no-op */\n },\n updateConversations: () => {\n /* no-op */\n },\n})\n","import MarkdownContent from '@patternfly/chatbot/dist/dynamic/MarkdownContent'\nimport { Alert } from '@patternfly/react-core'\nimport React from 'react'\n\n/**\n * Displays the model's internal reasoning text in an expandable info alert.\n *\n * @param think - The thinking/reasoning text produced by the model.\n */\nexport const ThinkInfo: React.FC<{\n think: string\n}> = ({ think }) => {\n return (\n <Alert variant='info' title='Thinking' isExpandable>\n <MarkdownContent content={think} />\n </Alert>\n )\n}\n","import { ToolCall } from '@langchain/core/messages/tool'\nimport { Alert } from '@patternfly/react-core'\nimport WrenchIcon from '@patternfly/react-icons/dist/esm/icons/wrench-icon'\nimport React from 'react'\n\n/**\n * Displays a single tool call in an info alert.\n *\n * @param call - The {@link ToolCall} object containing the tool name and arguments.\n * @param index - The position of this tool call in the list, used as the React `key`.\n */\nexport const ToolCallsInfo: React.FC<{\n call: ToolCall\n index: number\n}> = ({ call, index }) => {\n return (\n <Alert key={index} variant='info' customIcon={<WrenchIcon />} title={call.name} isInline>\n <p>Args: {JSON.stringify(call.args)}</p>\n </Alert>\n )\n}\n","import { PageContext } from '@hawtio/react/ui'\nimport { AIMessage } from '@langchain/core/messages'\nimport { ToolCall } from '@langchain/core/messages/tool'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport { Button, Flex } from '@patternfly/react-core'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { aiService } from '../common/ai-service'\nimport { ChatbotContext } from './context'\nimport { log } from './globals'\nimport { ThinkInfo } from './ThinkInfo'\nimport { ToolCallsInfo } from './ToolCallsInfo'\n\n/**\n * Renders Approve / Reject buttons for a pending set of tool calls.\n *\n * When the user clicks **Approve**, the tool calls are executed\n * and the conversation is updated with the result.\n * When the user clicks **Reject**, the tool calls are cancelled\n * and a \"Rejected\" user message is appended to the conversation.\n *\n * @param toolCalls - The list of {@link ToolCall} objects awaiting user approval.\n */\nexport const ToolCallsApprove: React.FC<{\n toolCalls: ToolCall[]\n messageId: string\n}> = ({ toolCalls, messageId }) => {\n const { username } = useContext(PageContext)\n const { messages, setAnnouncement, setIsSendButtonDisabled, updateConversations } = useContext(ChatbotContext)\n const messagesRef = useRef(messages)\n\n useEffect(() => {\n messagesRef.current = messages\n }, [messages])\n\n const removeApproveButtons = (messages: MessageProps[]) => {\n return messages.map(m =>\n m.id === messageId ? { ...m, extraContent: { ...m.extraContent, afterMainContent: undefined } } : m,\n )\n }\n\n const approve = async (toolCalls: ToolCall[]) => {\n log.debug('ToolCallsApprove - Approved', messagesRef.current)\n\n setIsSendButtonDisabled(true)\n const newMessages = removeApproveButtons([...messagesRef.current])\n newMessages.push(aiService.createUserMessage(username, 'Approved'))\n newMessages.push(aiService.createLoadingBotMessage())\n updateConversations(newMessages)\n setAnnouncement(`User approved tool usage. Message from Bot is loading.`)\n\n const dialogId = newMessages[0]!.id!\n const loadedMessages = [...newMessages]\n const answer = await aiService.invokeTools(dialogId, toolCalls, (intermediateAnswer: AIMessage) => {\n // Remove loading, insert intermediate tool-calls message, re-add loading\n loadedMessages.pop()\n loadedMessages.push(aiService.toBotMessage(intermediateAnswer, true, ThinkInfo, ToolCallsInfo, ToolCallsApprove))\n loadedMessages.push(aiService.createLoadingBotMessage())\n updateConversations([...loadedMessages])\n })\n loadedMessages.pop()\n const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove)\n loadedMessages.push(botMessage)\n updateConversations([...loadedMessages])\n setAnnouncement(`Message from Bot: ${answer}`)\n // Keep send button disabled if waiting for user to approve/reject further tool calls\n if (!aiService.hasToolCalls(answer)) {\n setIsSendButtonDisabled(false)\n }\n }\n\n const reject = () => {\n log.debug('ToolCallsApprove - Rejected', messagesRef.current)\n const currentMessages = messagesRef.current\n const dialogId = currentMessages[0]?.id\n if (dialogId) {\n aiService.rejectTools(dialogId, toolCalls)\n }\n const newMessages = removeApproveButtons([...currentMessages])\n newMessages.push(aiService.createUserMessage(username, 'Rejected'))\n updateConversations(newMessages)\n setIsSendButtonDisabled(false)\n }\n\n return (\n <Flex columnGap={{ default: 'columnGapSm' }}>\n <Button variant='primary' onClick={() => approve(toolCalls)}>\n Approve\n </Button>\n <Button variant='secondary' onClick={reject}>\n Reject\n </Button>\n </Flex>\n )\n}\n","import { PageContext } from '@hawtio/react/ui'\nimport Chatbot, { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'\nimport ChatbotContent from '@patternfly/chatbot/dist/dynamic/ChatbotContent'\nimport ChatbotConversationHistoryNav, {\n Conversation,\n} from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'\nimport ChatbotFooter, { ChatbotFootnote } from '@patternfly/chatbot/dist/dynamic/ChatbotFooter'\nimport ChatbotHeader, {\n ChatbotHeaderActions,\n ChatbotHeaderCloseButton,\n ChatbotHeaderMain,\n ChatbotHeaderMenu,\n ChatbotHeaderTitle,\n} from '@patternfly/chatbot/dist/dynamic/ChatbotHeader'\nimport ChatbotWelcomePrompt from '@patternfly/chatbot/dist/dynamic/ChatbotWelcomePrompt'\nimport Message, { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar'\nimport MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox'\nimport { Content, Label } from '@patternfly/react-core'\nimport React, { Dispatch, useContext, useEffect, useRef, useState } from 'react'\nimport { AIMessage } from '@langchain/core/messages'\nimport { aiService } from '../common/ai-service'\nimport { ChatbotContext } from './context'\nimport { log } from './globals'\nimport { ThinkInfo } from './ThinkInfo'\nimport { ToolCallsApprove } from './ToolCallsApprove'\nimport { ToolCallsInfo } from './ToolCallsInfo'\n\nexport const ChatbotPanel: React.FC<{\n title: string\n displayMode: ChatbotDisplayMode\n}> = ({ title, displayMode }) => {\n const { setMessages, dialogs, conversations } = useContext(ChatbotContext)\n const [isDrawerOpen, setIsDrawerOpen] = useState(false)\n const [filteredConversations, setFilteredConversations] = useState<Conversation[]>(conversations)\n\n const onSelectItemInHistory = (selected: string) => {\n log.debug('Selected conversation with ID:', selected)\n const dialog = dialogs.find(c => c.id === selected)\n if (dialog) {\n setMessages(dialog.messages)\n setIsDrawerOpen(false)\n }\n }\n\n const handleSearchTextChange = (value: string) => {\n if (value.trim() === '') {\n setFilteredConversations(conversations)\n return\n }\n\n const filtered = conversations.filter(c => c.text.toLowerCase().includes(value.toLowerCase()))\n log.debug('Filtered conversations:', filtered)\n setFilteredConversations(filtered)\n }\n\n return (\n <Chatbot isCompact displayMode={displayMode}>\n <ChatbotConversationHistoryNav\n isCompact\n drawerPanelContentProps={{ isResizable: true, minSize: '200px' }}\n displayMode={displayMode}\n onDrawerToggle={() => {\n setIsDrawerOpen(!isDrawerOpen)\n setFilteredConversations(conversations)\n }}\n isDrawerOpen={isDrawerOpen}\n setIsDrawerOpen={setIsDrawerOpen}\n onSelectActiveItem={(_e, selectedItem) => onSelectItemInHistory(String(selectedItem))}\n conversations={[...filteredConversations].reverse()}\n onNewChat={() => {\n setIsDrawerOpen(false)\n setFilteredConversations(conversations)\n setMessages([])\n }}\n handleTextInputChange={handleSearchTextChange}\n drawerContent={\n <>\n <ChatbotPanelHeader\n isDrawerOpen={isDrawerOpen}\n setIsDrawerOpen={setIsDrawerOpen}\n title={title}\n hasCloseButton={displayMode === ChatbotDisplayMode.drawer}\n />\n <ChatbotPanelContent />\n <ChatbotPanelFooter />\n </>\n }\n />\n </Chatbot>\n )\n}\n\nconst ChatbotPanelHeader: React.FC<{\n isDrawerOpen: boolean\n setIsDrawerOpen: Dispatch<React.SetStateAction<boolean>>\n title: string\n hasCloseButton: boolean\n}> = ({ isDrawerOpen, setIsDrawerOpen, title, hasCloseButton }) => {\n const { setIsChatbotOpen } = useContext(ChatbotContext)\n const modelName = aiService.getModel()?.name\n\n return (\n <ChatbotHeader>\n <ChatbotHeaderMain>\n <ChatbotHeaderMenu aria-expanded={isDrawerOpen} onMenuToggle={() => setIsDrawerOpen(!isDrawerOpen)} />\n <ChatbotHeaderTitle>\n <Content component='h2'>{title}</Content>\n </ChatbotHeaderTitle>\n </ChatbotHeaderMain>\n <ChatbotHeaderActions>\n {modelName && <Label variant='outline'>{modelName}</Label>}\n {hasCloseButton && <ChatbotHeaderCloseButton onClick={() => setIsChatbotOpen(false)} />}\n </ChatbotHeaderActions>\n </ChatbotHeader>\n )\n}\n\nconst ChatbotPanelContent: React.FC = () => {\n const { messages, announcement } = useContext(ChatbotContext)\n const { username } = useContext(PageContext)\n const scrollToBottomRef = useRef<HTMLDivElement>(null)\n\n const welcomeTitle = `Hello, ${username}!`\n const welcomeDescription = 'How can I help you manage or diagnose your Java application?'\n\n useEffect(() => {\n if (messages.length > 2) {\n scrollToBottomRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n }, [messages])\n\n return (\n <ChatbotContent>\n <MessageBox announcement={announcement}>\n {messages.length === 0 && <ChatbotWelcomePrompt title={welcomeTitle} description={welcomeDescription} />}\n {messages.map((message, index) => (\n <React.Fragment key={message.id}>\n {index === messages.length - 1 && <div ref={scrollToBottomRef} />}\n <Message key={message.id} {...message} />\n </React.Fragment>\n ))}\n </MessageBox>\n </ChatbotContent>\n )\n}\n\nconst ChatbotPanelFooter: React.FC = () => {\n const { username } = useContext(PageContext)\n const { messages, setAnnouncement, isSendButtonDisabled, setIsSendButtonDisabled, updateConversations } =\n useContext(ChatbotContext)\n const messagesRef = useRef(messages)\n\n useEffect(() => {\n messagesRef.current = messages\n }, [messages])\n\n const handleSend = async (message: string) => {\n if (!message.trim()) {\n return\n }\n log.debug('Send', messagesRef.current)\n\n setIsSendButtonDisabled(true)\n const newMessages: MessageProps[] = []\n newMessages.push(...messagesRef.current)\n newMessages.push(aiService.createUserMessage(username, message))\n newMessages.push(aiService.createLoadingBotMessage())\n updateConversations(newMessages)\n // make announcement to assistive devices that new messages have been added\n setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`)\n log.debug('handleSend - new messages:', newMessages)\n\n const dialogId = newMessages[0]!.id!\n const loadedMessages: MessageProps[] = [...newMessages]\n\n const onMessage = (intermediateAnswer: AIMessage) => {\n // Remove loading, insert intermediate tool-calls message, re-add loading\n loadedMessages.pop()\n loadedMessages.push(aiService.toBotMessage(intermediateAnswer, true, ThinkInfo, ToolCallsInfo, ToolCallsApprove))\n loadedMessages.push(aiService.createLoadingBotMessage())\n updateConversations([...loadedMessages])\n }\n\n const answer = await (newMessages.length === 2\n ? aiService.newChat(dialogId, { message }, onMessage)\n : aiService.chat(dialogId, message, onMessage))\n log.debug('handleSend - loaded messages:', loadedMessages)\n // Remove the loading message, replace with the final bot message\n loadedMessages.pop()\n const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove)\n loadedMessages.push(botMessage)\n updateConversations([...loadedMessages])\n setAnnouncement(`Message from Bot: ${answer}`)\n // Keep send button disabled if waiting for user to approve/reject tool calls\n if (!aiService.hasToolCalls(answer)) {\n setIsSendButtonDisabled(false)\n }\n }\n\n return (\n <ChatbotFooter>\n <MessageBar\n onSendMessage={m => handleSend(String(m))}\n hasAttachButton={false}\n isSendButtonDisabled={isSendButtonDisabled}\n />\n <ChatbotFootnote label='AI may be inaccurate. Please verify important information.' />\n </ChatbotFooter>\n )\n}\n","import { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'\nimport { PageSection } from '@patternfly/react-core'\nimport React from 'react'\nimport './Chat.css'\nimport { ChatbotPanel } from './ChatbotPanel'\nimport { ChatbotContext, useChatbot } from './context'\n\nexport const Chat: React.FC = () => {\n const chatbotContext = useChatbot()\n\n return (\n <ChatbotContext.Provider value={chatbotContext}>\n <PageSection id='chat-content' hasBodyWrapper={false} isFilled padding={{ default: 'noPadding' }}>\n <ChatbotPanel title='AI Chat' displayMode={ChatbotDisplayMode.embedded} />\n </PageSection>\n </ChatbotContext.Provider>\n )\n}\n","export * from './Chat'\n","import { Logger } from '@hawtio/react'\n\nexport const pluginName = 'hawtio-ai-jmx'\nexport const pluginTitle = 'AI JMX'\nexport const pluginPath = '/ai-jmx'\n\nexport const log = Logger.get(pluginName)\n\nexport const PARAM_KEY_NODE_ID = 'nid'\n","import { EVENT_REFRESH, eventService, MBeanNode, MBeanTree, PluginNodeSelectionContext, workspace } from '@hawtio/react'\nimport { createContext, useContext, useEffect, useRef, useState } from 'react'\nimport { To, useNavigate, useSearchParams } from 'react-router'\nimport { log, PARAM_KEY_NODE_ID, pluginName, pluginPath } from './globals'\n\n/**\n * Custom React hook for using JMX MBean tree.\n */\nexport function useMBeanTree(): MBeanTreeContext {\n const [tree, setTree] = useState(MBeanTree.createEmpty(pluginName))\n const [loaded, setLoaded] = useState(false)\n const { selectedNode, setSelectedNode } = useContext(PluginNodeSelectionContext)\n const navigate = useNavigate()\n const [searchParams, setSearchParams] = useSearchParams()\n\n /*\n * Need to preserve the selected node between re-renders since the\n * populateTree function called via the refresh listener does not\n * cache the value and stores it as null\n */\n const refSelectedNode = useRef<MBeanNode | null>()\n refSelectedNode.current = selectedNode\n\n const populateTree = async () => {\n const wkspTree = await workspace.getTree()\n setTree(wkspTree)\n\n const nodeId = searchParams.get(PARAM_KEY_NODE_ID)\n if (nodeId && nodeId !== refSelectedNode.current?.id) {\n log.debug('Restore selected node with nid:', nodeId)\n // Try to restore node from URL\n const urlNode = wkspTree.find(node => node.id === nodeId)\n if (urlNode) {\n setSelectedNode(urlNode)\n refSelectedNode.current = urlNode\n } else {\n // Clear nid as it is invalid\n log.debug('Clear invalid nid:', nodeId)\n searchParams.delete(PARAM_KEY_NODE_ID)\n setSearchParams(searchParams)\n }\n }\n\n if (!refSelectedNode.current) return\n\n const path = [...refSelectedNode.current.path()]\n\n // Expand the nodes to redisplay the path\n wkspTree.forEach(path, node => {\n node.defaultExpanded = true\n })\n\n // Ensure the new version of the selected node is selected\n const newSelected = wkspTree.navigate(...path)\n if (newSelected) {\n setSelectedNode(newSelected)\n // Reset to base path with nid to sync URL with restored selection\n navigate(pluginPathWithNodeId(newSelected, searchParams))\n } else {\n // Node no longer exists - clear selection and go to base path\n navigate(pluginPath)\n }\n }\n\n useEffect(() => {\n const loadTree = async () => {\n await populateTree()\n setLoaded(true)\n }\n\n const listener = () => {\n setLoaded(false)\n loadTree()\n }\n eventService.onRefresh(listener)\n\n loadTree()\n\n return () => eventService.removeListener(EVENT_REFRESH, listener)\n }, [])\n\n return { tree, loaded, selectedNode, setSelectedNode }\n}\n\n/**\n * Build URL query string with nid parameter, preserving other existing params\n * @param node - The node to encode\n * @param searchParams - The current URL search params to preserve, defaults to the ones from the window location\n */\nexport function pluginPathWithNodeId(\n node: MBeanNode,\n searchParams: URLSearchParams = new URLSearchParams(window.location.search),\n): Partial<To> {\n searchParams.set(PARAM_KEY_NODE_ID, node.id)\n const query = `?${searchParams.toString()}`\n return { pathname: pluginPath, search: query }\n}\n\ntype MBeanTreeContext = {\n tree: MBeanTree\n loaded: boolean\n selectedNode: MBeanNode | null\n setSelectedNode: (selected: MBeanNode | null) => void\n}\n\nexport const MBeanTreeContext = createContext<MBeanTreeContext>({\n tree: MBeanTree.createEmpty(pluginName),\n loaded: false,\n selectedNode: null,\n setSelectedNode: () => {\n /* no-op */\n },\n})\n",".jmx-split {\n display: flex;\n flex-direction: row;\n height: calc(100vh - 85px);\n}\n\n.gutter {\n background-color: #eee;\n background-repeat: no-repeat;\n background-position: 50%;\n}\n\n.gutter.gutter-horizontal {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');\n cursor: col-resize;\n}\n","#jmx-content {\n height: 100%;\n}\n\nsection#jmx-content-header.pf-v6-c-page__main-section {\n display: block;\n}\n\n#jmx-content-main > article {\n overflow: auto;\n}\n","import { AIMessage } from '@langchain/core/messages'\nimport { aiService } from '../common/ai-service'\n\nconst SYSTEM_MESSAGES = {\n diagnosis: `You are a helpful assistant diagnosing a JMX MBean based on its attribute values.\nGiven the following ObjectName and attribute values, identify any potential issues or anomalies.\nProvide suggestions for further investigation or resolution if applicable.\nRespond in a concise manner.`,\n} as const\n\nexport interface IJmxAiService {\n diagnoseMessage(objectName: string, attributes: string): string\n}\n\nclass JmxAiService implements IJmxAiService {\n systemMessage(): string {\n return SYSTEM_MESSAGES.diagnosis\n }\n\n diagnoseMessage(objectName: string, attributes: string): string {\n return `ObjectName:\n~~~\n${objectName}\n~~~\nAttribute values:\n~~~\n${attributes}\n~~~\nWhat potential issues or anomalies do you see?`\n }\n}\n\nexport const jmxAiService = new JmxAiService()\n","export function isObject(value: unknown): value is object {\n const type = typeof value\n return value != null && (type === 'object' || type === 'function')\n}\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && !Number.isNaN(value)\n}\n\nexport function stringSorter(a: string, b: string, sortDesc?: boolean): number {\n let res = a.localeCompare(b)\n if (sortDesc) {\n res *= -1\n }\n return res\n}\n\nexport function objectSorter(aValue: unknown, bValue: unknown, sortDesc?: boolean) {\n if (isNumber(aValue)) {\n // Numeric sort\n if (!sortDesc) {\n return (aValue as number) - (bValue as number)\n }\n return (bValue as number) - (aValue as number)\n } else {\n // String sort\n return stringSorter(aValue as string, bValue as string, sortDesc)\n }\n}\n\n/**\n * Return true if the string is either null or empty.\n */\nexport function isBlank(str?: string): boolean {\n if (str === undefined || str === null) {\n return true\n }\n if (typeof str !== 'string') {\n // not null but also not a string...\n return false\n }\n\n return str.trim().length === 0\n}\n\n/**\n * Will format a property to a standard human readable string with its spaces.\n * It will respect MBean and leave it together\n * @param str The property to transform\n * @returns The property with its proper spaces\n */\nexport function humanizeLabels(str: string): string {\n return str\n .split('-')\n .filter(str => !isBlank(str))\n .map(str => str.replace(/^./, str => str.toUpperCase()))\n .join(' ')\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/\\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')\n .replace('M Bean', 'MBean')\n .replace('Mbean', 'MBean')\n .replace(/^./, str => str.toUpperCase())\n .replace(/ +/, ' ')\n .trim()\n}\n\n/**\n * Escapes the mbean for Jolokia GET requests.\n *\n * @param mbean the MBean\n */\nexport function escapeMBean(mbean: string): string {\n return encodeURI(applyJolokiaEscapeRules(mbean))\n}\n\n/**\n * Applies the Jolokia escaping rules to the MBean name.\n * See: https://jolokia.org/reference/html/manual/jolokia_protocol.html#_escaping_rules_in_get_requests\n *\n * @param mbean the MBean\n */\nfunction applyJolokiaEscapeRules(mbean: string): string {\n return mbean.replace(/!/g, '!!').replace(/\\//g, '!/').replace(/\"/g, '!\"')\n}\n","import { AttributeValues, eventService, jolokiaService } from '@hawtio/react'\nimport {\n JolokiaErrorResponse,\n JolokiaFetchErrorResponse,\n JolokiaRequest,\n JolokiaSuccessResponse,\n RequestOptions,\n} from 'jolokia.js'\nimport { log } from '../globals'\nimport { escapeMBean } from '../util'\n\nclass AttributeService {\n private handles: number[] = []\n\n private requestOptions(): RequestOptions {\n // serializeLong = false\n return {}\n }\n\n private setupConfig(request: JolokiaRequest): JolokiaRequest {\n // serializeLong = false\n return request\n }\n\n async read(mbean: string): Promise<AttributeValues> {\n return await jolokiaService.readAttributes(mbean, this.requestOptions())\n }\n\n async readWithCallback(mbean: string, callback: (attrs: AttributeValues) => void): Promise<void> {\n const attrs = await jolokiaService.readAttributes(mbean, this.requestOptions())\n callback(attrs)\n }\n\n async register(\n request: JolokiaRequest,\n callback: (response: JolokiaSuccessResponse | JolokiaErrorResponse | JolokiaFetchErrorResponse) => void,\n ) {\n const handle = await jolokiaService.register(this.setupConfig(request), callback)\n log.debug('Register handle:', handle)\n this.handles.push(handle)\n }\n\n unregisterAll() {\n log.debug('Unregister all handles:', this.handles)\n this.handles.forEach(handle => jolokiaService.unregister(handle))\n this.handles = []\n }\n\n async buildUrl(mbean: string, attribute: string): Promise<string> {\n const jolokiaUrl = await jolokiaService.getFullJolokiaUrl()\n return `${jolokiaUrl}/read/${escapeMBean(mbean)}/${attribute}`\n }\n\n async canInvoke(mbean: string, attribute: string, type: string): Promise<boolean> {\n return true\n /*\n const aclMBean = await rbacService.getACLMBean()\n if (!aclMBean) {\n // Always allow invocation when client-side RBAC is not available\n return true\n }\n\n const operation = 'canInvoke(java.lang.String,java.lang.String,[Ljava.lang.String;)'\n const args = [mbean, `set${attribute}`, [type]]\n return jolokiaService.execute(aclMBean, operation, args) as Promise<boolean>\n */\n }\n\n async update(mbeanName: string, attribute: string, value: unknown) {\n await jolokiaService.writeAttribute(mbeanName, attribute, value, this.requestOptions())\n eventService.notify({ type: 'success', message: `Updated attribute: ${attribute}` })\n }\n\n async bulkRequest(requests: JolokiaRequest[]) {\n return jolokiaService.bulkRequest(requests.map(this.setupConfig))\n }\n}\n\nexport const attributeService = new AttributeService()\n","import { AttributeModal, AttributeValues, HawtioEmptyCard, HawtioLoadingCard } from '@hawtio/react'\nimport { PageContext } from '@hawtio/react/ui'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport {\n Button,\n Drawer,\n DrawerContent,\n DrawerContentBody,\n Panel,\n Toolbar,\n ToolbarContent,\n ToolbarItem,\n} from '@patternfly/react-core'\nimport { MonitoringIcon } from '@patternfly/react-icons'\nimport { Table, Tbody, Td, Th, Thead, ThProps, Tr } from '@patternfly/react-table'\nimport Jolokia, { JolokiaErrorResponse, JolokiaFetchErrorResponse, JolokiaSuccessResponse } from 'jolokia.js'\nimport React, { useContext, useEffect, useState } from 'react'\nimport { ChatbotContext } from '../../chat/context'\nimport { ThinkInfo } from '../../chat/ThinkInfo'\nimport { ToolCallsApprove } from '../../chat/ToolCallsApprove'\nimport { ToolCallsInfo } from '../../chat/ToolCallsInfo'\nimport { aiService } from '../../common/ai-service'\nimport { MBeanTreeContext } from '../context'\nimport { log } from '../globals'\nimport { jmxAiService } from '../jmx-ai-service'\nimport { isObject, objectSorter } from '../util'\nimport { attributeService } from './attribute-service'\n\nexport const Attributes: React.FC = () => {\n const { selectedNode } = useContext(MBeanTreeContext)\n const [attributes, setAttributes] = useState<AttributeValues>({})\n const [isReading, setIsReading] = useState(true)\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc')\n const [selected, setSelected] = useState({ name: '', value: '' })\n const [reload, setReload] = useState(false)\n\n useEffect(() => {\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {\n return\n }\n\n setIsReading(true)\n const { objectName } = selectedNode\n attributeService.readWithCallback(objectName, attrs => {\n setAttributes(attrs)\n setIsReading(false)\n })\n\n attributeService.register(\n { type: 'read', mbean: objectName },\n (response: JolokiaSuccessResponse | JolokiaErrorResponse | JolokiaFetchErrorResponse) => {\n if (response && !Jolokia.isError(response as JolokiaSuccessResponse | JolokiaErrorResponse)) {\n setAttributes((response as JolokiaSuccessResponse).value as AttributeValues)\n }\n },\n )\n\n return () => attributeService.unregisterAll()\n }, [selectedNode])\n\n useEffect(() => {\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName || !reload) {\n return\n }\n\n setIsReading(true)\n const { objectName } = selectedNode\n attributeService.readWithCallback(objectName, attrs => {\n setAttributes(attrs)\n setIsReading(false)\n })\n\n setReload(false)\n }, [selectedNode, reload])\n\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {\n return null\n }\n\n if (isReading) {\n return <HawtioLoadingCard />\n }\n\n const rows: { name: string; value: string }[] = Object.entries(attributes).map(([name, value]) => ({\n name: name,\n value: isObject(value) ? JSON.stringify(value) : String(value),\n }))\n\n if (rows.length === 0) {\n return <HawtioEmptyCard message='This MBean has no attributes.' />\n }\n\n const selectAttribute = (attribute: { name: string; value: string }) => {\n setSelected(attribute)\n if (!isModalOpen) {\n setIsModalOpen(true)\n }\n }\n\n const getSortParams = (): ThProps['sort'] => ({\n sortBy: {\n index: 0,\n direction: sortDirection,\n defaultDirection: 'asc', // starting sort direction when first sorting a column. Defaults to 'asc'\n },\n onSort: (_event, _index, direction) => {\n setSortDirection(direction)\n },\n columnIndex: 0,\n })\n\n const panelContent = (\n <AttributeModal\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n onUpdate={() => setReload(true)}\n input={selected}\n />\n )\n\n const attributesTable = (\n <div id='attribute-table-with-panel'>\n <AiJmxToolbar attributes={attributes} />\n <Table aria-label='Attributes' variant='compact'>\n <Thead>\n <Tr>\n <Th sort={getSortParams()}>Attribute</Th>\n <Th>Value</Th>\n </Tr>\n </Thead>\n <Tbody>\n {rows\n .sort((a, b) => objectSorter(a.name, b.name, sortDirection === 'desc'))\n .map((att, index) => (\n <Tr\n key={att.name + '-' + index}\n isClickable\n isRowSelected={selected.name === att.name}\n onRowClick={() => selectAttribute(att)}\n >\n <Td>{att.name}</Td>\n <Td>{att.value}</Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </div>\n )\n\n return (\n <Panel>\n <Drawer isExpanded={isModalOpen} className='pf-m-inline-on-2xl'>\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody hasPadding>{attributesTable}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n </Panel>\n )\n}\n\nconst AiJmxToolbar: React.FC<{\n attributes: AttributeValues\n}> = ({ attributes }) => {\n const { selectedNode } = useContext(MBeanTreeContext)\n const { username } = useContext(PageContext)\n const { setAnnouncement, setIsChatbotOpen, updateConversations } = useContext(ChatbotContext)\n\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {\n return null\n }\n const { objectName } = selectedNode\n\n const diagnose = async () => {\n setIsChatbotOpen(true)\n const attrsValue = JSON.stringify(attributes)\n log.debug('Attributes:', attrsValue)\n\n const systemMessage = jmxAiService.systemMessage()\n const diagnoseMessage = jmxAiService.diagnoseMessage(objectName, attrsValue)\n const newMessages: MessageProps[] = []\n newMessages.push(aiService.createUserMessage(username, diagnoseMessage))\n newMessages.push(aiService.createLoadingBotMessage())\n updateConversations(newMessages, `Diagnose ${objectName}`)\n setAnnouncement('Diagnosis in progress...')\n log.debug('diagnose - new messages:', newMessages)\n\n const dialogId = newMessages[0]!.id!\n const answer = await aiService.newChat(dialogId, { message: diagnoseMessage, system: systemMessage })\n const loadedMessages: MessageProps[] = []\n loadedMessages.push(...newMessages)\n log.debug('diagnose - loaded messages:', loadedMessages)\n // Remove the loading message\n loadedMessages.pop()\n const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove)\n loadedMessages.push(botMessage)\n updateConversations(loadedMessages)\n setAnnouncement('Diagnosis complete.')\n }\n\n return (\n <Toolbar id='ai-jmx-toolbar'>\n <ToolbarContent>\n <ToolbarItem>\n <Button variant='primary' size='sm' icon={<MonitoringIcon />} onClick={diagnose}>\n Diagnose\n </Button>\n </ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n )\n}\n","export { Attributes } from './Attributes'\n","import { AttributeTable, Chart, JmxContentMBeans, MBeanNode, Operations } from '@hawtio/react'\nimport { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'\nimport {\n Button,\n Content,\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelBody,\n DrawerPanelContent,\n EmptyState,\n Nav,\n NavItem,\n NavList,\n PageGroup,\n PageSection,\n Title,\n Toolbar,\n ToolbarItem,\n} from '@patternfly/react-core'\nimport { right } from '@patternfly/react-core/dist/esm/helpers/Popper/thirdparty/popper-core'\nimport { CubesIcon } from '@patternfly/react-icons/dist/esm/icons/cubes-icon'\nimport React, { useContext, useRef } from 'react'\nimport { Navigate, NavLink, Route, Routes, useLocation } from 'react-router'\nimport { ChatbotPanel } from '../chat/ChatbotPanel'\nimport { ChatbotContext, useChatbot } from '../chat/context'\nimport './JmxContent.css'\nimport { Attributes } from './attributes'\nimport { MBeanTreeContext, pluginPathWithNodeId } from './context'\nimport { pluginPath } from './globals'\n\nexport const JmxContent: React.FunctionComponent = () => {\n const { selectedNode } = useContext(MBeanTreeContext)\n const { pathname, search } = useLocation()\n const chatbotContext = useChatbot()\n const { isChatbotOpen, setIsChatbotOpen } = chatbotContext\n const drawerRef = useRef<HTMLDivElement>(undefined)\n\n if (!selectedNode) {\n return (\n <PageSection hasBodyWrapper={false} isFilled>\n <EmptyState headingLevel='h1' icon={CubesIcon} titleText='Select MBean' variant='full' />\n </PageSection>\n )\n }\n\n const mBeanApplicable = (node: MBeanNode) => Boolean(node.objectName)\n const mBeanCollectionApplicable = (node: MBeanNode) => Boolean(node.children?.every(child => child.objectName))\n const hasAnyApplicableMBean = (node: MBeanNode) =>\n Boolean(node.objectName) || Boolean(node.children?.some(child => child.objectName))\n\n const tableSelector = (node: MBeanNode) => {\n const tablePriorityList = [\n { condition: mBeanApplicable, element: Attributes },\n { condition: mBeanCollectionApplicable, element: AttributeTable },\n ]\n\n return tablePriorityList.find(entry => entry.condition(node))?.element ?? JmxContentMBeans\n }\n\n const allNavItems = [\n { id: 'attributes', title: 'Attributes', component: tableSelector(selectedNode), isApplicable: () => true },\n { id: 'operations', title: 'Operations', component: Operations, isApplicable: mBeanApplicable },\n { id: 'chart', title: 'Chart', component: Chart, isApplicable: hasAnyApplicableMBean },\n ]\n\n /* Filter the nav items to those applicable to the selected node */\n const navItems = allNavItems.filter(nav => nav.isApplicable(selectedNode))\n\n const searchWithNid = (pluginPathWithNodeId(selectedNode, new URLSearchParams(search)) as { search: string }).search\n\n const mbeanNav = (\n <Nav aria-label='MBean Nav' variant='horizontal-subnav'>\n <NavList>\n {navItems.map(nav => (\n <NavItem key={nav.id} isActive={pathname === `${pluginPath}/${nav.id}`}>\n <NavLink to={{ pathname: nav.id, search }}>{nav.title}</NavLink>\n </NavItem>\n ))}\n </NavList>\n </Nav>\n )\n\n const mbeanRoutes = navItems.map(nav => (\n <Route key={nav.id} path={nav.id} element={React.createElement(nav.component)} />\n ))\n\n const jmxAiToolbar = (\n <Toolbar id='jmx-ai-toolbar' style={{ float: right }}>\n <ToolbarItem>\n <Button variant='secondary' size='sm' onClick={() => setIsChatbotOpen(!isChatbotOpen)}>\n Chat\n </Button>\n </ToolbarItem>\n </Toolbar>\n )\n\n const jmxContent = (\n <PageGroup id='jmx-content'>\n <PageSection id='jmx-content-header' hasBodyWrapper={false}>\n {jmxAiToolbar}\n <Title headingLevel='h1'>{selectedNode.name}</Title>\n <Content component='small'>{selectedNode.objectName}</Content>\n </PageSection>\n <PageSection type='tabs' hasBodyWrapper={false}>\n {mbeanNav}\n </PageSection>\n <PageSection\n id='jmx-content-main'\n padding={{ default: 'noPadding' }}\n hasOverflowScroll\n aria-label='jmx-content-main'\n hasBodyWrapper={false}\n >\n <Routes>\n {mbeanRoutes}\n <Route\n key='root'\n path='/'\n element={<Navigate to={{ pathname: navItems[0]?.id ?? '', search: searchWithNid }} />}\n />\n </Routes>\n </PageSection>\n </PageGroup>\n )\n\n const onDrawerExpand = () => {\n drawerRef.current && drawerRef.current.focus()\n }\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize='500px' minSize='200px'>\n <DrawerPanelBody>\n <ChatbotPanel title='AI Diagnosis' displayMode={ChatbotDisplayMode.drawer} />\n </DrawerPanelBody>\n </DrawerPanelContent>\n )\n\n return (\n <ChatbotContext.Provider value={chatbotContext}>\n <Drawer isExpanded={isChatbotOpen} isInline onExpand={onDrawerExpand}>\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{jmxContent}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n </ChatbotContext.Provider>\n )\n}\n","#jmx-tree-view.pf-v6-c-tree-view {\n --pf-v6-c-tree-view__node--indent--base: 1rem;\n --pf-v6-c-tree-view__node--nested-indent--base: 1rem;\n --pf-v6-c-tree-view--m-guides__node--before--Width: 1.25rem;\n --pf-v6-c-tree-view--m-guides__node--before--Height: 1px;\n --pf-v6-c-tree-view--m-guides__node--before--InsetBlockStart: 0.625rem;\n --pf-v6-c-tree-view--m-guides__node--before--BackgroundColor: var(--pf-t--global--border--color--default);\n --pf-v6-c-tree-view--m-guides__list-item--before--Width: 1px;\n --pf-v6-c-tree-view--m-guides__list-item--before--Height: 100%;\n --pf-v6-c-tree-view--m-guides__list-item--before--BackgroundColor: var(--pf-t--global--border--color--default);\n --pf-v6-c-tree-view--m-guides__list-item--last-child--before--Height: 0.68rem;\n --pf-v6-c-tree-view--m-guides__list-node--guide-width--base: 0.5rem;\n --pf-v6-c-tree-view--m-guides--guide-left--base--offset: 1.4rem;\n}\n#jmx-tree-view.pf-v6-c-tree-view .pf-m-selectable {\n --pf-v6-c-tree-view--m-guides__node--before--Width: 0.5rem;\n}\n#jmx-tree-view .pf-v6-c-tree-view__list {\n height: 100%;\n}\n\n#jmx-tree-view > .pf-v6-c-tree-view__list {\n max-height: 83vh;\n overflow: auto;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node {\n padding-top: 0;\n padding-bottom: 0;\n align-items: center;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node:has(button.pf-v6-c-tree-view__node-toggle) {\n --pf-v6-c-tree-view--m-guides__node--before--Width: 0.5rem;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-toggle {\n padding: 0;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-text {\n padding: 0 4px;\n font-size: small;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-icon {\n padding: 0 4px;\n flex-shrink: 0;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-text {\n overflow-x: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n","import { MBeanNode, MBeanTree, PluginTreeViewToolbar } from '@hawtio/react'\nimport { TreeView, TreeViewDataItem } from '@patternfly/react-core'\nimport React, { ChangeEvent, useContext, useEffect, useState } from 'react'\nimport { useNavigate } from 'react-router'\nimport './JmxTreeView.css'\nimport { MBeanTreeContext, pluginPathWithNodeId } from './context'\n\n/**\n * Expansion requires more than 2 states since the expandAll\n * must be removed completely to defer to the expanded state\n * of each data node\n */\nenum ExpansionValue {\n /**\n * should revert to the expanded state of the data\n */\n Default,\n /**\n * all data should be expanded\n */\n ExpandAll,\n /**\n * all data should be collapsed\n */\n CollapseAll,\n}\n\nexport const JmxTreeView: React.FunctionComponent = () => {\n const { tree, selectedNode, setSelectedNode } = useContext(MBeanTreeContext)\n const [expanded, setExpanded] = useState(ExpansionValue.Default)\n const [filteredTree, setFilteredTree] = useState(tree.getTree())\n const navigate = useNavigate()\n\n /**\n * Listen for changes to the tree that may occur as a result\n * of events being monitored by the Tree:Watcher in workspace\n * eg. new endpoint being created\n */\n useEffect(() => {\n setFilteredTree(tree.getTree())\n }, [tree])\n\n const onSearch = (event: ChangeEvent<HTMLInputElement>) => {\n // Ensure no node from the 'old' filtered is lingering\n setSelectedNode(null)\n setExpanded(ExpansionValue.Default)\n const input = event.target.value\n\n if (!input) setFilteredTree(tree.getTree())\n\n const treeElements = MBeanTree.filter(tree.getTree(), node => node.name.toLowerCase().includes(input.toLowerCase()))\n\n if (treeElements.length === 0) setFilteredTree(tree.getTree())\n else {\n setFilteredTree(treeElements)\n setExpanded(ExpansionValue.ExpandAll)\n }\n }\n\n const onSelect = (event: React.MouseEvent<Element, MouseEvent>, item: TreeViewDataItem) => {\n const node = item as MBeanNode\n setSelectedNode(node)\n navigate(pluginPathWithNodeId(node))\n }\n\n const setAllExpanded = (value: boolean) => {\n setExpanded(value ? ExpansionValue.ExpandAll : ExpansionValue.CollapseAll)\n }\n\n const expandedProp = (): object => {\n switch (expanded) {\n case ExpansionValue.ExpandAll:\n return { allExpanded: true }\n case ExpansionValue.CollapseAll:\n return { allExpanded: false }\n default:\n return {}\n }\n }\n\n return (\n <TreeView\n id='jmx-tree-view'\n data={filteredTree}\n hasGuides={true}\n hasSelectableNodes={true}\n activeItems={selectedNode ? [selectedNode] : []}\n {...expandedProp()}\n onSelect={onSelect}\n toolbar={<PluginTreeViewToolbar onSearch={onSearch} onSetExpanded={setAllExpanded} />}\n />\n )\n}\n","import { EmptyState, PageSection, Spinner } from '@patternfly/react-core'\nimport { CubesIcon } from '@patternfly/react-icons/dist/esm/icons/cubes-icon'\nimport React from 'react'\nimport Split from 'react-split'\nimport { MBeanTreeContext, useMBeanTree } from './context'\nimport './Jmx.css'\nimport { JmxContent } from './JmxContent'\nimport { JmxTreeView } from './JmxTreeView'\n\nexport const Jmx: React.FunctionComponent = () => {\n const { tree, loaded, selectedNode, setSelectedNode } = useMBeanTree()\n\n if (!loaded) {\n return (\n <PageSection hasBodyWrapper={false}>\n <Spinner aria-label='Loading MBean tree' />\n </PageSection>\n )\n }\n\n if (tree.isEmpty()) {\n return (\n <PageSection hasBodyWrapper={false}>\n <EmptyState headingLevel='h1' icon={CubesIcon} titleText='No MBeans found' variant='full' />\n </PageSection>\n )\n }\n\n return (\n <MBeanTreeContext.Provider value={{ tree, loaded, selectedNode, setSelectedNode }}>\n <Split className='jmx-split' sizes={[30, 70]} minSize={200} gutterSize={5}>\n <div>\n <JmxTreeView />\n </div>\n <div>\n <JmxContent />\n </div>\n </Split>\n </MBeanTreeContext.Provider>\n )\n}\n","export * from './Jmx'\nexport * from './JmxContent'\nexport * from './JmxTreeView'\n","import { HawtioPlugin, configManager } from '@hawtio/react'\nimport '@patternfly/chatbot/dist/css/main.css'\nimport { aiChat } from './chat'\nimport { aiCommon } from './common'\nimport { aiJmx } from './jmx-ai'\n\n/**\n * The entry function for the plugin exposed to Hawtio.\n *\n * The default name for the function is \"plugin\". If you want to use the name other\n * than the default one, you need to specify the name using {HawtioPlugin#setPluginEntry()}\n * method when registering the plugin to JMX MBean server.\n *\n * <code>\n * HawtioPlugin plugin = new HawtioPlugin();\n * plugin.setPluginEntry(\"registerMyPlugin\");\n * </code>\n *\n * @see src/main/java/io/hawt/example/spring/boot/SampleSpringBootService.java\n */\nexport const plugin: HawtioPlugin = () => {\n aiCommon()\n aiJmx()\n aiChat()\n}\n\n// Register the custom plugin version to Hawtio\n// See package.json \"replace-version\" script for how to replace the version placeholder with a real version\nconfigManager.addProductInfo('Hawtio AI Plugin', '__PACKAGE_VERSION_PLACEHOLDER__')\n","import { hawtio, type HawtioPlugin } from '@hawtio/react'\nimport { log, pluginName, pluginPath, pluginTitle } from './globals'\n\nconst order = 42\n\nexport const aiChat: HawtioPlugin = () => {\n log.info('Loading', pluginName)\n\n hawtio.addDeferredPlugin(pluginName, async () => {\n return import('./ui').then(({ Chat }) => {\n return {\n id: pluginName,\n title: pluginTitle,\n path: pluginPath,\n order,\n component: Chat,\n isActive: async () => true,\n }\n })\n })\n}\n","import { HawtioPlugin, preferencesRegistry } from '@hawtio/react'\nimport { AiPreferences } from '../common/AiPreferences'\nimport { pluginName, pluginTitle } from './globals'\n\nconst order = 40\n\nexport const aiCommon: HawtioPlugin = () => {\n preferencesRegistry.add(pluginName, pluginTitle, AiPreferences, order)\n}\n","import {\n Button,\n CardBody,\n Content,\n Form,\n FormGroup,\n FormSection,\n FormSelect,\n FormSelectOption,\n InputGroup,\n InputGroupItem,\n NumberInput,\n Switch,\n TextInput,\n} from '@patternfly/react-core'\nimport EyeIcon from '@patternfly/react-icons/dist/esm/icons/eye-icon'\nimport EyeSlashIcon from '@patternfly/react-icons/dist/esm/icons/eye-slash-icon'\nimport { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'\nimport React, { useState } from 'react'\nimport { MODELS, PROVIDERS } from './ai-model'\nimport {\n AiOptions,\n DEFAULT_MAX_AUTO_TOOL_STEPS,\n DEFAULT_TOOL_PERMISSIONS,\n aiPreferencesService,\n} from './ai-preferences-service'\nimport './AiPreferences.css'\nimport { WORKSPACE_TOOLS_META } from './tools'\n\nexport const AiPreferences: React.FC = () => {\n const [options, setOptions] = useState(aiPreferencesService.loadOptions())\n\n return (\n <CardBody>\n <Form id='ai-prefs-form' isHorizontal>\n <ModelForm options={options} setOptions={setOptions} />\n <PermissionForm options={options} setOptions={setOptions} />\n </Form>\n </CardBody>\n )\n}\n\nconst ModelForm: React.FC<{\n options: AiOptions\n setOptions: React.Dispatch<React.SetStateAction<AiOptions>>\n}> = ({ options, setOptions }) => {\n const [provider, setProvider] = useState<string>(options.model.provider)\n const [models, setModels] = useState(MODELS.filter(m => m.provider === provider))\n const [passwordHidden, setPasswordHidden] = useState(true)\n\n const updateProvider = (provider: string) => {\n setProvider(provider)\n setModels(MODELS.filter(m => m.provider === provider))\n }\n\n const updateModel = (updated: string) => {\n const model = MODELS.find(m => m.id === updated)\n if (model) {\n aiPreferencesService.saveOptions({ model })\n setOptions({ ...options, model })\n }\n }\n\n const updateToken = (updated?: string) => {\n aiPreferencesService.saveOptions({ token: updated })\n setOptions({ ...options, token: updated })\n }\n\n return (\n <FormSection title='Model' titleElement='h2'>\n <FormGroup fieldId='ai-prefs-form-provider' label='Provider'>\n <FormSelect\n id='ai-prefs-form-provider-input'\n aria-label='Form Select Provider'\n value={provider}\n onChange={(_, p) => updateProvider(p)}\n >\n {PROVIDERS.map((p, i) => (\n <FormSelectOption key={i} value={p} label={p} />\n ))}\n </FormSelect>\n </FormGroup>\n <FormGroup fieldId='ai-prefs-form-model' label='Model'>\n <FormSelect\n id='ai-prefs-form-model-input'\n aria-label='Form Select Model'\n value={options.model.id}\n onChange={(_, id) => updateModel(id)}\n >\n {models.map(m => (\n <FormSelectOption key={m.id} value={m.id} label={m.name} />\n ))}\n </FormSelect>\n </FormGroup>\n <FormGroup fieldId='ai-prefs-form-token' label='API Key / Token (optional)'>\n <InputGroup>\n <InputGroupItem isFill>\n <TextInput\n id='ai-prefs-form-token-input'\n aria-label='Form Select Token'\n type={passwordHidden ? 'password' : 'text'}\n value={options.token}\n onChange={(_, t) => updateToken(t)}\n />\n </InputGroupItem>\n <InputGroupItem>\n <Button\n variant='control'\n onClick={() => setPasswordHidden(!passwordHidden)}\n aria-label={passwordHidden ? 'Show password' : 'Hide password'}\n >\n {passwordHidden ? <EyeIcon /> : <EyeSlashIcon />}\n </Button>\n </InputGroupItem>\n </InputGroup>\n </FormGroup>\n </FormSection>\n )\n}\n\nconst PermissionForm: React.FC<{\n options: AiOptions\n setOptions: React.Dispatch<React.SetStateAction<AiOptions>>\n}> = ({ options, setOptions }) => {\n const maxAutoToolSteps = options.maxAutoToolSteps ?? DEFAULT_MAX_AUTO_TOOL_STEPS\n const toolPermissions = options.toolPermissions ?? DEFAULT_TOOL_PERMISSIONS\n\n const updateMaxAutoToolSteps = (updated: number) => {\n aiPreferencesService.saveOptions({ maxAutoToolSteps: updated })\n setOptions({ ...options, maxAutoToolSteps: updated })\n }\n\n const updatePermission = (tool: string, updated: boolean) => {\n const updatedPermissions = { ...toolPermissions, [tool]: updated }\n aiPreferencesService.saveOptions({ toolPermissions: updatedPermissions })\n setOptions({ ...options, toolPermissions: updatedPermissions })\n }\n\n return (\n <FormSection title='Permission control' titleElement='h2'>\n <FormGroup fieldId='ai-prefs-form-max-steps' label='Max auto-approve steps'>\n <NumberInput\n id='ai-prefs-form-max-steps-input'\n aria-label='Form select max auto-approve steps'\n value={options.maxAutoToolSteps}\n min={1}\n max={100}\n onMinus={() => updateMaxAutoToolSteps(Math.max(1, maxAutoToolSteps - 1))}\n onPlus={() => updateMaxAutoToolSteps(Math.min(100, maxAutoToolSteps + 1))}\n onChange={e => {\n const value = parseInt((e.target as HTMLInputElement).value)\n if (!isNaN(value) && value >= 1 && value <= 100) {\n updateMaxAutoToolSteps(value)\n }\n }}\n />\n </FormGroup>\n <FormGroup fieldId='ai-prefs-form-tool-permissions' style={{ display: 'flex' }}>\n <Content component='small'>\n Enable auto-approve to allow a tool to run without asking for confirmation each time.\n </Content>\n <Table\n aria-label='Tool permissions'\n variant='compact'\n borders={false}\n isStriped\n isStickyHeader\n style={{ marginTop: '0.5rem' }}\n >\n <Thead>\n <Tr>\n <Th modifier='fitContent'>Tool</Th>\n <Th modifier='wrap'>Description</Th>\n <Th modifier='fitContent'>Auto-approve</Th>\n </Tr>\n </Thead>\n <Tbody>\n {WORKSPACE_TOOLS_META.map(({ name, description }) => (\n <Tr key={name}>\n <Td dataLabel='Tool'>\n <b>{name}</b>\n </Td>\n <Td dataLabel='Description'>{description}</Td>\n <Td dataLabel='Auto-approve' textCenter>\n <Switch\n id={`ai-prefs-tool-switch-${name}`}\n aria-label={`Auto-approve ${name}`}\n isChecked={toolPermissions[name] ?? false}\n onChange={(_, checked) => updatePermission(name, checked)}\n />\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </FormGroup>\n </FormSection>\n )\n}\n","import { hawtio, helpRegistry, workspace, type HawtioPlugin } from '@hawtio/react'\nimport { log, pluginName, pluginPath, pluginTitle } from './globals'\nimport help from './help.md'\n\nconst order = 41\n\nexport const aiJmx: HawtioPlugin = () => {\n log.info('Loading', pluginName)\n\n hawtio.addDeferredPlugin(pluginName, async () => {\n return import('./ui').then(({ Jmx }) => {\n return {\n id: pluginName,\n title: pluginTitle,\n path: pluginPath,\n order,\n component: Jmx,\n knownQueryParams: ['nid'],\n isActive: async () => workspace.hasMBeans(),\n }\n })\n })\n helpRegistry.add(pluginName, pluginTitle, help, order)\n}\n","# 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"],"mappings":"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","names":["import_react","pluginName","pluginTitle","log","init_globals","import_react","init_globals","workspace","jolokiaService","log","log","import_react","init_globals","import_react","init_globals","log","userAvatar","botAvatar","ThinkInfo","ToolCallsInfo","ToolCallsApprove","content","messages","import_react","MarkdownContent","import_react_core","import_jsx_runtime","WrenchIcon","import_react_core","import_react","import_jsx_runtime","messages","toolCalls","import_ui","import_react_core","import_react","import_jsx_runtime","Chatbot","ChatbotConversationHistoryNav","ChatbotHeader","ChatbotContent","MessageBox","ChatbotWelcomePrompt","React","Message","ChatbotFooter","MessageBar","import_Chatbot","import_react_core","import_jsx_runtime","init_Chat","init_Chat","import_react","pluginName","pluginTitle","pluginPath","log","init_globals","pluginName","log","pluginPath","import_react","init_context","init_globals","import_react","init_globals","log","import_react","import_ui","import_react_core","import_react_table","import_jsx_runtime","init_context","init_globals","Jolokia","log","import_react","import_Chatbot","import_react_core","import_react_router","import_jsx_runtime","init_JmxContent","init_context","init_globals","pluginPath","React","import_react","import_react_core","import_react_router","import_jsx_runtime","init_JmxTreeView","init_context","import_react_core","import_cubes_icon","import_jsx_runtime","init_Jmx","init_context","init_JmxContent","init_JmxTreeView","Split","ui_exports","init_ui","init_Jmx","init_JmxContent","init_JmxTreeView","import_react","import_react","Chat","import_react","import_react_core","import_react","import_jsx_runtime","provider","EyeIcon","EyeSlashIcon","init_globals","order","pluginName","pluginTitle","import_react","init_globals","order","log","pluginName","Jmx","pluginTitle","pluginPath"]}
1
+ {"version":3,"sources":["../src/ai-plugin/chat/globals.ts","../src/ai-plugin/chat/Chat.css","../src/ai-plugin/common/ai-model.ts","../src/ai-plugin/common/ai-preferences-service.ts","../src/ai-plugin/common/globals.ts","../src/ai-plugin/common/workspace.ts","../src/ai-plugin/common/tools.ts","../src/ai-plugin/common/ai-service.ts","../src/ai-plugin/chat/model.ts","../src/ai-plugin/chat/context.ts","../src/ai-plugin/chat/ThinkInfo.tsx","../src/ai-plugin/chat/ToolCallsInfo.tsx","../src/ai-plugin/chat/ToolCallsApprove.tsx","../src/ai-plugin/chat/ChatbotPanel.tsx","../src/ai-plugin/chat/Chat.tsx","../src/ai-plugin/chat/ui.ts","../src/ai-plugin/jmx-ai/globals.ts","../src/ai-plugin/jmx-ai/context.ts","../src/ai-plugin/jmx-ai/Jmx.css","../src/ai-plugin/jmx-ai/JmxContent.css","../src/ai-plugin/jmx-ai/jmx-ai-service.ts","../src/ai-plugin/jmx-ai/util.ts","../src/ai-plugin/jmx-ai/attributes/attribute-service.ts","../src/ai-plugin/jmx-ai/attributes/Attributes.tsx","../src/ai-plugin/jmx-ai/attributes/index.ts","../src/ai-plugin/jmx-ai/JmxContent.tsx","../src/ai-plugin/jmx-ai/JmxTreeView.css","../src/ai-plugin/jmx-ai/JmxTreeView.tsx","../src/ai-plugin/jmx-ai/Jmx.tsx","../src/ai-plugin/jmx-ai/ui.ts","../src/ai-plugin/index.ts","../src/ai-plugin/chat/index.ts","../src/ai-plugin/common/index.ts","../src/ai-plugin/common/AiPreferences.tsx","../src/ai-plugin/jmx-ai/index.ts","../src/ai-plugin/jmx-ai/help.md"],"sourcesContent":["import { Logger } from '@hawtio/react'\n\nexport const pluginName = 'hawtio-ai-chat'\nexport const pluginTitle = 'AI Chat'\nexport const pluginPath = '/ai-chat'\n\nexport const log = Logger.get(pluginName)\n",".pf-v6-c-page__main-container:has(#chat-content) {\n height: 100%;\n margin: 0;\n}\n","export const PROVIDERS = ['openai', 'anthropic', 'google-genai', 'ollama'] as const\nexport type AiProvider = (typeof PROVIDERS)[number]\n\nexport type AiModel = {\n id: string\n name: string\n tool: boolean\n provider: AiProvider\n}\n\nexport const MODELS: AiModel[] = [\n // OpenAI models\n { id: 'gpt-5.5', name: 'GPT-5.5', tool: true, provider: 'openai' },\n { id: 'gpt-5.4', name: 'GPT-5.4', tool: true, provider: 'openai' },\n { id: 'gpt-5.4-mini', name: 'GPT-5.4 mini', tool: true, provider: 'openai' },\n\n // Anthropic Claude models\n { id: 'claude-opus-4-7', name: 'Claude Opus 4.7', tool: true, provider: 'anthropic' },\n { id: 'claude-sonnet-4-6', name: 'Claude Sonnet 4.6', tool: true, provider: 'anthropic' },\n { id: 'claude-haiku-4-5', name: 'Claude Haiku 4.5', tool: true, provider: 'anthropic' },\n\n // Google Gemini models\n { id: 'gemini-3.5-flash', name: 'Gemini 3.5 Flash', tool: true, provider: 'google-genai' },\n { id: 'gemini-3.1-flash-lite', name: 'Gemini 3.1 Flash-Lite', tool: true, provider: 'google-genai' },\n { id: 'gemini-3.1-pro', name: 'Gemini 3.1 Pro', tool: true, provider: 'google-genai' },\n\n // Ollama models\n { id: 'granite4.1:3b', name: 'Granite 4.1 3B', tool: true, provider: 'ollama' },\n { id: 'llama3:latest', name: 'Llama 3', tool: false, provider: 'ollama' },\n { id: 'llama3.2:latest', name: 'Llama 3.2', tool: true, provider: 'ollama' },\n { id: 'gemma4:e4b', name: 'Gemma 4 4B', tool: true, provider: 'ollama' },\n { id: 'gemma4:e4b-mlx', name: 'Gemma 4 4B MLX', tool: true, provider: 'ollama' },\n { id: 'phi4:latest', name: 'Phi 4', tool: false, provider: 'ollama' },\n { id: 'phi3.5:latest', name: 'Phi 3.5', tool: false, provider: 'ollama' },\n { id: 'qwen3.5:4b', name: 'Qwen 3.5 4B', tool: true, provider: 'ollama' },\n { id: 'qwen3.5:4b-mlx', name: 'Qwen 3.5 4B MLX', tool: true, provider: 'ollama' },\n { id: 'qwen3.5:latest', name: 'Qwen 3.5', tool: true, provider: 'ollama' },\n] as const\n","import { AiModel, MODELS } from './ai-model'\nimport { aiService } from './ai-service'\n\nexport const STORAGE_KEY_PREFERENCES = 'ai.preferences'\n\n/**\n * Per-tool auto-approval map.\n * Key: tool name (e.g. 'listMBeans'), Value: true = auto-approve without prompting.\n */\nexport type ToolPermissions = Record<string, boolean>\n\nexport type AiOptions = {\n model: AiModel\n token?: string\n toolPermissions?: ToolPermissions\n /**\n * Maximum number of consecutive auto-approved tool-call steps per chat turn.\n * Prevents runaway execution when the LLM repeatedly emits approved tool calls.\n */\n maxAutoToolSteps?: number\n}\n\n/**\n * Workspace-cache-only tools are auto-approved by default (no remote side effects).\n * Jolokia-backed tools default to OFF so the user must explicitly approve them.\n */\nexport const DEFAULT_TOOL_PERMISSIONS: ToolPermissions = {\n listMBeans: true,\n getMBeanInfo: true,\n searchMBeans: true,\n readMBeanAttribute: false,\n writeMBeanAttribute: false,\n executeMBeanOperation: false,\n}\n\nexport const DEFAULT_MAX_AUTO_TOOL_STEPS = 10\n\nexport const DEFAULT_OPTIONS: AiOptions = {\n model: MODELS[0]!,\n toolPermissions: DEFAULT_TOOL_PERMISSIONS,\n maxAutoToolSteps: DEFAULT_MAX_AUTO_TOOL_STEPS,\n} as const\n\nexport interface IAiPreferencesService {\n loadOptions(): AiOptions\n saveOptions(options: Partial<AiOptions>): void\n}\n\nclass AiPreferencesService implements IAiPreferencesService {\n loadOptions(): AiOptions {\n const item = localStorage.getItem(STORAGE_KEY_PREFERENCES)\n const savedOptions = item ? JSON.parse(item) : {}\n return { ...DEFAULT_OPTIONS, ...savedOptions }\n }\n\n saveOptions(options: Partial<AiOptions>) {\n const updated = { ...this.loadOptions(), ...options }\n localStorage.setItem(STORAGE_KEY_PREFERENCES, JSON.stringify(updated))\n if (options.model) {\n aiService.reset(options.model)\n }\n }\n}\n\nexport const aiPreferencesService = new AiPreferencesService()\n","import { Logger } from '@hawtio/react'\n\nexport const pluginName = 'hawtio-ai'\nexport const pluginTitle = 'AI'\n\nexport const log = Logger.get(pluginName)\n","import { IJolokiaService, IWorkspace, OptimisedMBeanInfo, jolokiaService, workspace } from '@hawtio/react'\nimport { log } from './globals'\n\nexport interface IWorkspaceExtension {\n /** List all ObjectNames available in the workspace cache. */\n listMBeans(): Promise<string[]>\n\n /**\n * Return the OptimisedMBeanInfo for a specific MBean from the workspace cache.\n * Returns null if the MBean is not found in the cache.\n */\n getMBeanInfo(objectName: string): Promise<OptimisedMBeanInfo | null>\n\n /** Read the current value of an MBean attribute via Jolokia. */\n readMBeanAttribute(objectName: string, attribute: string): Promise<unknown>\n\n /** Write a value to a writable MBean attribute via Jolokia. */\n writeMBeanAttribute(objectName: string, attribute: string, value: unknown): Promise<unknown>\n\n /** Execute an MBean operation via Jolokia. */\n executeMBeanOperation(objectName: string, operation: string, args?: unknown[]): Promise<unknown>\n}\n\n/**\n * Extends the Hawtio workspace with MBean query and Jolokia operation methods\n * for use by AI tools. No LangChain dependency — pure Hawtio logic only.\n *\n * Read-only methods (workspace cache):\n * - listMBeans()\n * - getMBeanInfo(objectName)\n *\n * Jolokia methods (live server calls):\n * - readMBeanAttribute(objectName, attribute)\n * - writeMBeanAttribute(objectName, attribute, value)\n * - executeMBeanOperation(objectName, operation, args?)\n */\nclass WorkspaceExtension implements IWorkspaceExtension {\n constructor(\n private readonly workspace: IWorkspace,\n private readonly jolokiaService: IJolokiaService,\n ) {}\n\n async listMBeans(): Promise<string[]> {\n log.debug('workspace - listMBeans called')\n const tree = await this.workspace.getTree()\n const flat = tree.flatten()\n const result = Object.keys(flat).sort()\n log.debug('workspace - listMBeans result count:', result.length)\n return result\n }\n\n async getMBeanInfo(objectName: string): Promise<OptimisedMBeanInfo | null> {\n log.debug('workspace - getMBeanInfo called:', objectName)\n const tree = await this.workspace.getTree()\n const flat = tree.flatten()\n const mbeanInfo = flat[objectName]?.mbean ?? null\n if (!mbeanInfo) {\n log.debug('workspace - getMBeanInfo: not found:', objectName)\n }\n return mbeanInfo\n }\n\n async readMBeanAttribute(objectName: string, attribute: string): Promise<unknown> {\n log.debug('workspace - readMBeanAttribute called:', objectName, attribute)\n return this.jolokiaService.readAttribute(objectName, attribute)\n }\n\n async writeMBeanAttribute(objectName: string, attribute: string, value: unknown): Promise<unknown> {\n log.debug('workspace - writeMBeanAttribute called:', objectName, attribute, value)\n return this.jolokiaService.writeAttribute(objectName, attribute, value)\n }\n\n async executeMBeanOperation(objectName: string, operation: string, args?: unknown[]): Promise<unknown> {\n log.debug('workspace - executeMBeanOperation called:', objectName, operation, args)\n return this.jolokiaService.execute(objectName, operation, args)\n }\n}\n\nexport const workspaceExtension: IWorkspaceExtension = new WorkspaceExtension(workspace, jolokiaService)\n","import { MBeanNode, workspace } from '@hawtio/react'\nimport { DynamicStructuredTool } from '@langchain/core/tools'\nimport { z } from 'zod'\nimport { log } from './globals'\nimport { workspaceExtension } from './workspace'\n\nfunction listMBeansTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'listMBeans',\n description: `\n List all MBean ObjectNames available in the Hawtio workspace cache.\n Use this to discover what MBeans are present before querying details.\n `,\n schema: z.object({}),\n func: async (): Promise<string> => {\n log.debug('tools - listMBeans called')\n const result = await workspaceExtension.listMBeans()\n return JSON.stringify(result)\n },\n })\n}\n\nfunction getMBeanInfoTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'getMBeanInfo',\n description: `\n Return the attribute schema (type, description, read/write flag) and operation definitions\n (arguments, return type, description) for a specific MBean.\n Call this before readMBeanAttribute or executeMBeanOperation to inspect available fields.\n `,\n schema: z.object({\n objectName: z.string().describe(\"JMX ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n }),\n func: async ({ objectName }): Promise<string> => {\n log.debug('tools - getMBeanInfo called:', objectName)\n const info = await workspaceExtension.getMBeanInfo(objectName)\n if (!info) {\n return JSON.stringify({ error: `MBean not found: ${objectName}` })\n }\n return JSON.stringify({ objectName, attr: info.attr, op: info.op })\n },\n })\n}\n\nfunction searchMBeansTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'searchMBeans',\n description: `\n Search MBeans by JMX domain and property key/value pairs.\n Returns a list of matching ObjectNames.\n Use this to narrow down MBeans by type or name, e.g. domain='java.lang', properties='{\"type\":\"Memory\"}'.\n `,\n schema: z.object({\n domain: z.string().describe(\"JMX domain to search in, e.g. 'java.lang'\"),\n properties: z\n .string()\n .describe('JSON string of JMX property key/value pairs to match, e.g. \\'{\"type\":\"Memory\"}\\''),\n }),\n func: async ({ domain, properties }): Promise<string> => {\n log.debug('tools - searchMBeans called:', domain, properties)\n let parsed: unknown\n try {\n parsed = JSON.parse(properties)\n } catch {\n return JSON.stringify({ error: `Invalid JSON for properties: ${properties}` })\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n return JSON.stringify({ error: `properties must be a JSON object, got: ${properties}` })\n }\n const nodes: MBeanNode[] = await workspace.findMBeans(domain, parsed as Record<string, unknown>)\n const result = nodes.map((n: MBeanNode) => n.objectName).filter((s): s is string => s !== undefined)\n log.debug('tools - searchMBeans result count:', result.length)\n return JSON.stringify(result)\n },\n })\n}\n\nfunction readMBeanAttributeTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'readMBeanAttribute',\n description: `\n Read the current value of an MBean attribute via Jolokia.\n This is a read-only operation with no side effects.\n Use getMBeanInfo first to confirm the attribute name and type.\n `,\n schema: z.object({\n objectName: z.string().describe(\"ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n attribute: z.string().describe(\"Name of the attribute to read, e.g. 'HeapMemoryUsage'\"),\n }),\n func: async ({ objectName, attribute }): Promise<string> => {\n log.debug('tools - readMBeanAttribute called:', objectName, attribute)\n try {\n const value = await workspaceExtension.readMBeanAttribute(objectName, attribute)\n return JSON.stringify({ objectName, attribute, value })\n } catch (e) {\n return JSON.stringify({ error: String(e) })\n }\n },\n })\n}\n\nfunction writeMBeanAttributeTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'writeMBeanAttribute',\n description: `\n Write a value to a writable MBean attribute via Jolokia.\n Verify rw=true with getMBeanInfo before calling this tool.\n `,\n schema: z.object({\n objectName: z.string().describe(\"ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n attribute: z.string().describe('Name of the attribute to write'),\n value: z.string().describe('JSON-encoded value to set, e.g. \"42\" or \"true\" or \"\\\\\"hello\\\\\"\"'),\n }),\n func: async ({ objectName, attribute, value }): Promise<string> => {\n log.debug('tools - writeMBeanAttribute called:', objectName, attribute, value)\n let parsed: unknown\n try {\n parsed = JSON.parse(value)\n } catch {\n parsed = value\n }\n try {\n const result = await workspaceExtension.writeMBeanAttribute(objectName, attribute, parsed)\n return JSON.stringify({ objectName, attribute, result })\n } catch (e) {\n return JSON.stringify({ error: String(e) })\n }\n },\n })\n}\n\nfunction executeMBeanOperationTool(): DynamicStructuredTool {\n return new DynamicStructuredTool({\n name: 'executeMBeanOperation',\n description: `\n Execute an MBean operation via Jolokia.\n Use getMBeanInfo to verify the operation signature before calling.\n For overloaded operations include the signature, e.g. 'gc()'.\n `,\n schema: z.object({\n objectName: z.string().describe(\"ObjectName of the target MBean, e.g. 'java.lang:type=Memory'\"),\n operation: z.string().describe(\"Operation name to invoke, e.g. 'gc' or 'gc()'\"),\n args: z\n .array(z.string())\n .optional()\n .describe('JSON-encoded arguments to pass to the operation, e.g. [\"value1\", \"42\"]'),\n }),\n func: async ({ objectName, operation, args }): Promise<string> => {\n log.debug('tools - executeMBeanOperation called:', objectName, operation, args)\n const parsedArgs = args?.map((a: string) => {\n try {\n return JSON.parse(a)\n } catch {\n return a\n }\n })\n try {\n const result = await workspaceExtension.executeMBeanOperation(objectName, operation, parsedArgs)\n return JSON.stringify({ objectName, operation, result })\n } catch (e) {\n return JSON.stringify({ error: String(e) })\n }\n },\n })\n}\n\n/** Returns all the workspace tools available in Hawtio AI. */\nexport function getWorkspaceTools(): DynamicStructuredTool[] {\n return [\n listMBeansTool(),\n getMBeanInfoTool(),\n searchMBeansTool(),\n readMBeanAttributeTool(),\n writeMBeanAttributeTool(),\n executeMBeanOperationTool(),\n ]\n}\n\n/** Metadata for all workspace tools, derived from tool definitions for the AI Preferences UI. */\nexport const WORKSPACE_TOOLS_META = getWorkspaceTools().map(({ name, description }) => ({ name, description }))\n","import { ChatAnthropic } from '@langchain/anthropic'\nimport { BaseLanguageModelInput } from '@langchain/core/language_models/base'\nimport {\n AIMessage,\n AIMessageChunk,\n BaseMessage,\n HumanMessage,\n SystemMessage,\n ToolMessage,\n} from '@langchain/core/messages'\nimport { ToolCall } from '@langchain/core/messages/tool'\nimport { Runnable } from '@langchain/core/runnables'\nimport { DynamicStructuredTool } from '@langchain/core/tools'\nimport { ChatGoogleGenerativeAI } from '@langchain/google-genai'\nimport { ChatOllama } from '@langchain/ollama'\nimport { ChatOpenAI } from '@langchain/openai'\nimport { MessageExtraContent, MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport botAvatar from '@patternfly/chatbot/patternfly-docs/content/extensions/chatbot/examples/Messages/patternfly_avatar.jpg'\nimport userAvatar from '@patternfly/react-core/dist/styles/assets/images/img_avatar-light.svg'\nimport { ComponentType, createElement } from 'react'\nimport { AiModel } from './ai-model'\nimport { aiPreferencesService } from './ai-preferences-service'\nimport { log } from './globals'\nimport { getWorkspaceTools } from './tools'\n\nconst BOT_NAME = 'Hawtio AI'\n\nconst TOOLS: DynamicStructuredTool[] = getWorkspaceTools()\nconst TOOLS_BY_NAME: Record<string, DynamicStructuredTool> = TOOLS.reduce(\n (acc, tool) => {\n acc[tool.name] = tool\n return acc\n },\n {} as Record<string, DynamicStructuredTool>,\n)\n\nexport type MessageWithThink = {\n content: string\n think?: string\n}\n\nexport type LLM = ChatOpenAI | ChatAnthropic | ChatGoogleGenerativeAI | ChatOllama\n\nexport interface IAiService {\n reset(model: AiModel): void\n getModel(): AiModel | undefined\n newChat(\n dialogId: string,\n initialMessage: { message: string; system?: string },\n onMessage?: (answer: AIMessage) => void,\n ): Promise<AIMessage | string>\n chat(dialogId: string, message: string, onMessage?: (answer: AIMessage) => void): Promise<AIMessage | string>\n invokeTools(\n dialogId: string,\n toolCalls: ToolCall[],\n onMessage?: (answer: AIMessage) => void,\n step?: number,\n ): Promise<AIMessage | string>\n hasToolCalls(answer: AIMessage | string): answer is AIMessage\n rejectTools(dialogId: string, toolCalls: ToolCall[]): void\n createUserMessage(name: string, content: string): MessageProps\n createLoadingBotMessage(): MessageProps\n createBotMessage(content: string, extraContent?: MessageExtraContent): MessageProps\n toBotMessage(\n answer: AIMessage | string,\n autoApproved: boolean,\n ThinkInfo: ComponentType<{ think: string }>,\n ToolCallsInfo: ComponentType<{ call: ToolCall; index: number }>,\n ToolCallsApprove: ComponentType<{ toolCalls: ToolCall[]; messageId: string }>,\n ): MessageProps\n}\n\nclass AiService implements IAiService {\n private model?: AiModel\n private llm?: LLM\n private llmWithTools?: Runnable<BaseLanguageModelInput, AIMessageChunk>\n private memory: Record<string, BaseMessage[]> = {}\n\n private appendToolMessages(messages: BaseMessage[], toolCalls: ToolCall[], content: string): void {\n for (const call of toolCalls) {\n messages.push(new ToolMessage({ tool_call_id: call.id ?? call.name, content }))\n }\n }\n\n reset(model: AiModel): void {\n if (this.model && this.model.id === model.id && this.llm && (!model.tool || this.llmWithTools)) {\n return\n }\n log.info('AI model to use:', model.id)\n // Reset the current memory\n this.memory = {}\n const { token } = aiPreferencesService.loadOptions()\n this.model = model\n try {\n switch (this.model.provider) {\n case 'openai':\n this.llm = new ChatOpenAI({\n model: this.model.id,\n apiKey: token,\n streaming: false,\n })\n break\n case 'anthropic':\n this.llm = new ChatAnthropic({\n model: this.model.id,\n apiKey: token,\n streaming: false,\n })\n break\n case 'google-genai':\n this.llm = new ChatGoogleGenerativeAI({\n model: this.model.id,\n apiKey: token,\n temperature: 0,\n disableStreaming: true,\n })\n break\n case 'ollama':\n default:\n this.llm = new ChatOllama({\n model: this.model.id,\n streaming: false,\n })\n }\n } catch (error) {\n // Mostly token is missing/invalid\n log.warn('Error initialising AI model:', error)\n this.llm = undefined\n }\n this.llmWithTools = undefined\n if (TOOLS.length !== 0 && this.model.tool) {\n this.llmWithTools = this.llm?.bindTools(TOOLS)\n }\n }\n\n private getLlm(): LLM | Runnable<BaseLanguageModelInput, AIMessageChunk> | undefined {\n if (!this.model || !this.llm) {\n const { model } = aiPreferencesService.loadOptions()\n this.reset(model)\n }\n return this.llmWithTools ?? this.llm\n }\n\n getModel(): AiModel | undefined {\n this.getLlm()\n return this.model\n }\n\n private async invoke(messages: BaseMessage[]): Promise<AIMessage | string> {\n // Lazy init model and llm\n const llm = this.getLlm()\n log.debug('Chatting with', this.model?.id, ':', messages)\n try {\n let answer: AIMessageChunk\n if (!llm) {\n throw new Error('AI model not configured')\n }\n answer = await llm.invoke(messages)\n\n if (answer.tool_calls && answer.tool_calls.length > 0) {\n log.debug('🛠️ calls:', answer.tool_calls)\n }\n log.debug('Answer:', answer)\n return answer\n } catch (error) {\n log.error('Error while chatting:', error)\n return String(error)\n }\n }\n\n newChat(\n dialogId: string,\n initialMessage: { message: string; system?: string },\n onMessage?: (answer: AIMessage) => void,\n ): Promise<AIMessage | string> {\n const { message, system } = initialMessage\n if (system) {\n this.memory[dialogId] = [new SystemMessage(system)]\n } else {\n this.memory[dialogId] = []\n }\n return this.chat(dialogId, message, onMessage)\n }\n\n hasToolCalls(answer: AIMessage | string): answer is AIMessage {\n return typeof answer !== 'string' && (answer.tool_calls?.length ?? 0) > 0\n }\n\n async chat(dialogId: string, message: string, onMessage?: (answer: AIMessage) => void): Promise<AIMessage | string> {\n let messages = this.memory[dialogId]\n if (!messages) {\n messages = []\n this.memory[dialogId] = messages\n }\n messages.push(new HumanMessage(message))\n const answer = await this.invoke(messages)\n if (typeof answer !== 'string') {\n messages.push(answer)\n }\n log.debug('Current messages:', messages)\n\n // If the LLM requests auto-approved tool calls, delegate to invokeTools which\n // handles the full auto-approve loop with a step limit.\n if (this.hasToolCalls(answer)) {\n const { toolPermissions } = aiPreferencesService.loadOptions()\n if (answer.tool_calls!.every(call => toolPermissions?.[call.name] === true)) {\n onMessage?.(answer)\n return this.invokeTools(dialogId, answer.tool_calls!, onMessage)\n }\n }\n\n return answer\n }\n\n /**\n * Executes the given tool calls and invokes the LLM with the results.\n * If the LLM responds with further tool calls that are all auto-approved,\n * this method recurses (up to {@link maxAutoToolSteps} times) to continue\n * the chain without interruption. Tool calls that are not auto-approved are\n * returned as-is so the caller can decide to approve or reject them.\n *\n * @param step - Current recursion depth; used to enforce the step limit.\n */\n async invokeTools(\n dialogId: string,\n toolCalls: ToolCall[],\n onMessage?: (answer: AIMessage) => void,\n step = 0,\n ): Promise<AIMessage | string> {\n if (!this.llmWithTools) {\n return 'Tool invocation not supported'\n }\n\n let messages = this.memory[dialogId]\n if (!messages) {\n messages = []\n this.memory[dialogId] = messages\n }\n\n const { toolPermissions, maxAutoToolSteps } = aiPreferencesService.loadOptions()\n if (step >= maxAutoToolSteps!) {\n const limitMessage = `Automatic tool-call step limit reached after ${maxAutoToolSteps} steps.`\n this.appendToolMessages(messages, toolCalls, limitMessage)\n log.warn(`Auto-tool execution stopped after ${maxAutoToolSteps} steps to prevent runaway execution.`)\n return `Stopped after ${maxAutoToolSteps} automatic tool-call steps. You can increase the limit in Preferences.`\n }\n\n try {\n for (const call of toolCalls) {\n log.debug('🛠️ Call:', call.name, JSON.stringify(call.args))\n const selectedTool = TOOLS_BY_NAME[call.name]\n const toolAnswer = await selectedTool?.invoke(call)\n if (toolAnswer) {\n log.debug('🛠️ ' + call.name + ':', toolAnswer)\n messages.push(toolAnswer)\n }\n }\n const answer = await this.llmWithTools.invoke(messages)\n if (answer) {\n messages.push(answer)\n }\n log.debug('Messages>>', messages)\n\n // If the LLM requests more auto-approved tool calls, recurse with incremented step counter\n if (this.hasToolCalls(answer) && answer.tool_calls!.every(call => toolPermissions?.[call.name] === true)) {\n onMessage?.(answer)\n return this.invokeTools(dialogId, answer.tool_calls!, onMessage, step + 1)\n }\n\n return answer\n } catch (error) {\n log.error('Error while invoking tools:', error)\n return String(error)\n }\n }\n\n rejectTools(dialogId: string, toolCalls: ToolCall[]): void {\n const messages = this.memory[dialogId]\n if (!messages) return\n this.appendToolMessages(messages, toolCalls, 'User rejected')\n log.debug(\n 'rejectTools - added rejection ToolMessages for:',\n toolCalls.map(c => c.name),\n )\n }\n\n private generateId(): string {\n return crypto.randomUUID()\n }\n\n createUserMessage(name: string, content: string): MessageProps {\n const id = this.generateId()\n return {\n id,\n role: 'user',\n content,\n name,\n avatar: userAvatar,\n timestamp: new Date().toLocaleString(),\n }\n }\n\n createLoadingBotMessage(): MessageProps {\n const id = this.generateId()\n return {\n id,\n role: 'bot',\n name: BOT_NAME,\n avatar: botAvatar,\n avatarProps: { style: { fontSize: '90%' } },\n content: 'API response goes here',\n isLoading: true,\n }\n }\n\n createBotMessage(content: string, extraContent?: MessageExtraContent): MessageProps {\n const id = this.generateId()\n return {\n id,\n role: 'bot',\n name: BOT_NAME,\n avatar: botAvatar,\n avatarProps: { style: { fontSize: '90%' } },\n content,\n extraContent,\n isLoading: false,\n timestamp: new Date().toLocaleString(),\n }\n }\n\n private extractThink(message: AIMessage): MessageWithThink {\n const content = message.content as string\n let think: string | undefined\n if (message.additional_kwargs?.reasoning_content) {\n think = message.additional_kwargs?.reasoning_content as string | undefined\n }\n return { content, think }\n }\n\n toBotMessage(\n answer: AIMessage | string,\n autoApproved: boolean,\n ThinkInfo: ComponentType<{ think: string }>,\n ToolCallsInfo: ComponentType<{ call: ToolCall; index: number }>,\n ToolCallsApprove: ComponentType<{ toolCalls: ToolCall[]; messageId: string }>,\n ): MessageProps {\n if (typeof answer === 'string') {\n // Error\n return this.createBotMessage(`Error: ${answer}`)\n }\n\n if (!answer.tool_calls || answer.tool_calls.length === 0) {\n // No tool calls — normal text response\n const { content, think } = this.extractThink(answer)\n const extraContent = think ? { beforeMainContent: createElement(ThinkInfo, { think }) } : undefined\n return this.createBotMessage(content, extraContent)\n }\n\n // Tool calls — show which tools are being used\n const toolCalls = answer.tool_calls\n const isMultiple = toolCalls.length > 1\n const toolNames = toolCalls\n .map(call => `**${call.name}**`)\n .filter((name, index, self) => self.indexOf(name) === index)\n .join(', ')\n const beforeMainContent = toolCalls.map((call, index) => createElement(ToolCallsInfo, { key: index, call, index }))\n\n if (autoApproved) {\n const content = `Auto-approved ${toolCalls.length} tool ${isMultiple ? 'calls' : 'call'}: ${toolNames}`\n return this.createBotMessage(content, { beforeMainContent })\n }\n\n const content = `${BOT_NAME} wants to use ${isMultiple ? 'tools' : 'a tool'}: ${toolNames}`\n const botMessage = this.createBotMessage(content)\n botMessage.extraContent = {\n beforeMainContent,\n afterMainContent: createElement(ToolCallsApprove, { toolCalls, messageId: botMessage.id! }),\n }\n return botMessage\n }\n}\n\nexport const aiService = new AiService()\n","import { Conversation } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\n\nexport class ChatbotDialog {\n public readonly id: string\n\n constructor(\n public messages: MessageProps[],\n private summary?: string,\n ) {\n this.id = messages[0]?.id ?? ''\n }\n\n setMessages(messages: MessageProps[]) {\n if (messages[0]?.id !== this.id) {\n throw new Error('Not the same dialog')\n }\n this.messages = [...messages]\n }\n\n createConversation(): Conversation {\n const text = this.summary ?? (this.messages[0]?.content ?? '').substring(0, 20)\n return { id: this.id, text }\n }\n}\n","import { Conversation } from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport { createContext, Dispatch, useState } from 'react'\nimport { log } from './globals'\nimport { ChatbotDialog } from './model'\n\n/**\n * Custom React hook for managing AI Chatbot state and conversation history.\n *\n * Provides state and controls for:\n * - Active messages and multi-dialog conversation history\n * - Assistive device announcements (accessibility)\n * - Drawer open/close visibility and send button state\n */\nexport function useChatbot(): ChatbotContext {\n const [messages, setMessages] = useState<MessageProps[]>([])\n const [dialogs, setDialogs] = useState<ChatbotDialog[]>([])\n const [conversations, setConversations] = useState<Conversation[]>([])\n const [announcement, setAnnouncement] = useState('')\n const [isChatbotOpen, setIsChatbotOpen] = useState(false)\n const [isSendButtonDisabled, setIsSendButtonDisabled] = useState(false)\n\n const updateConversations = (messages: MessageProps[], summary?: string) => {\n const dialogId = messages[0]?.id\n if (!dialogId) {\n return\n }\n setMessages(messages)\n let dialog = dialogs.find(d => d.id === dialogId)\n if (dialog) {\n dialog.setMessages(messages)\n } else {\n dialog = new ChatbotDialog(messages, summary)\n dialogs.push(dialog)\n }\n setDialogs([...dialogs])\n log.debug('Updated dialogs:', dialogs)\n\n if (!conversations.some(c => c.id === dialogId)) {\n const conversation = dialog.createConversation()\n conversations.push(conversation)\n setConversations([...conversations])\n log.debug('Updated conversations:', conversations)\n }\n }\n\n return {\n messages,\n setMessages,\n dialogs,\n setDialogs,\n conversations,\n setConversations,\n announcement,\n setAnnouncement,\n isChatbotOpen,\n setIsChatbotOpen,\n isSendButtonDisabled,\n setIsSendButtonDisabled,\n updateConversations,\n }\n}\n\nexport type ChatbotContext = {\n messages: MessageProps[]\n setMessages: Dispatch<React.SetStateAction<MessageProps[]>>\n dialogs: ChatbotDialog[]\n setDialogs: Dispatch<React.SetStateAction<ChatbotDialog[]>>\n conversations: Conversation[]\n setConversations: Dispatch<React.SetStateAction<Conversation[]>>\n announcement: string\n setAnnouncement: Dispatch<React.SetStateAction<string>>\n isChatbotOpen: boolean\n setIsChatbotOpen: (value: boolean) => void\n isSendButtonDisabled: boolean\n setIsSendButtonDisabled: (value: boolean) => void\n updateConversations: (messages: MessageProps[], summary?: string) => void\n}\n\nexport const ChatbotContext = createContext<ChatbotContext>({\n messages: [],\n setMessages: () => {\n /* no-op */\n },\n dialogs: [],\n setDialogs: () => {\n /* no-op */\n },\n conversations: [],\n setConversations: () => {\n /* no-op */\n },\n announcement: '',\n setAnnouncement: () => {\n /* no-op */\n },\n isChatbotOpen: false,\n setIsChatbotOpen: () => {\n /* no-op */\n },\n isSendButtonDisabled: false,\n setIsSendButtonDisabled: () => {\n /* no-op */\n },\n updateConversations: () => {\n /* no-op */\n },\n})\n","import MarkdownContent from '@patternfly/chatbot/dist/dynamic/MarkdownContent'\nimport { Alert } from '@patternfly/react-core'\nimport React from 'react'\n\n/**\n * Displays the model's internal reasoning text in an expandable info alert.\n *\n * @param think - The thinking/reasoning text produced by the model.\n */\nexport const ThinkInfo: React.FC<{\n think: string\n}> = ({ think }) => {\n return (\n <Alert variant='info' title='Thinking' isExpandable>\n <MarkdownContent content={think} />\n </Alert>\n )\n}\n","import { ToolCall } from '@langchain/core/messages/tool'\nimport { Alert } from '@patternfly/react-core'\nimport WrenchIcon from '@patternfly/react-icons/dist/esm/icons/wrench-icon'\nimport React from 'react'\n\n/**\n * Displays a single tool call in an info alert.\n *\n * @param call - The {@link ToolCall} object containing the tool name and arguments.\n * @param index - The position of this tool call in the list, used as the React `key`.\n */\nexport const ToolCallsInfo: React.FC<{\n call: ToolCall\n index: number\n}> = ({ call, index }) => {\n return (\n <Alert key={index} variant='info' customIcon={<WrenchIcon />} title={call.name} isInline>\n <p>Args: {JSON.stringify(call.args)}</p>\n </Alert>\n )\n}\n","import { PageContext } from '@hawtio/react/ui'\nimport { AIMessage } from '@langchain/core/messages'\nimport { ToolCall } from '@langchain/core/messages/tool'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport { Button, Flex } from '@patternfly/react-core'\nimport React, { useContext, useEffect, useRef } from 'react'\nimport { aiService } from '../common/ai-service'\nimport { ChatbotContext } from './context'\nimport { log } from './globals'\nimport { ThinkInfo } from './ThinkInfo'\nimport { ToolCallsInfo } from './ToolCallsInfo'\n\n/**\n * Renders Approve / Reject buttons for a pending set of tool calls.\n *\n * When the user clicks **Approve**, the tool calls are executed\n * and the conversation is updated with the result.\n * When the user clicks **Reject**, the tool calls are cancelled\n * and a \"Rejected\" user message is appended to the conversation.\n *\n * @param toolCalls - The list of {@link ToolCall} objects awaiting user approval.\n */\nexport const ToolCallsApprove: React.FC<{\n toolCalls: ToolCall[]\n messageId: string\n}> = ({ toolCalls, messageId }) => {\n const { username } = useContext(PageContext)\n const { messages, setAnnouncement, setIsSendButtonDisabled, updateConversations } = useContext(ChatbotContext)\n const messagesRef = useRef(messages)\n\n useEffect(() => {\n messagesRef.current = messages\n }, [messages])\n\n const removeApproveButtons = (messages: MessageProps[]) => {\n return messages.map(m =>\n m.id === messageId ? { ...m, extraContent: { ...m.extraContent, afterMainContent: undefined } } : m,\n )\n }\n\n const approve = async (toolCalls: ToolCall[]) => {\n log.debug('ToolCallsApprove - Approved', messagesRef.current)\n\n setIsSendButtonDisabled(true)\n const newMessages = removeApproveButtons([...messagesRef.current])\n newMessages.push(aiService.createUserMessage(username, 'Approved'))\n newMessages.push(aiService.createLoadingBotMessage())\n updateConversations(newMessages)\n setAnnouncement(`User approved tool usage. Message from Bot is loading.`)\n\n const dialogId = newMessages[0]!.id!\n const loadedMessages = [...newMessages]\n const answer = await aiService.invokeTools(dialogId, toolCalls, (intermediateAnswer: AIMessage) => {\n // Remove loading, insert intermediate tool-calls message, re-add loading\n loadedMessages.pop()\n loadedMessages.push(aiService.toBotMessage(intermediateAnswer, true, ThinkInfo, ToolCallsInfo, ToolCallsApprove))\n loadedMessages.push(aiService.createLoadingBotMessage())\n updateConversations([...loadedMessages])\n })\n loadedMessages.pop()\n const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove)\n loadedMessages.push(botMessage)\n updateConversations([...loadedMessages])\n setAnnouncement(`Message from Bot: ${answer}`)\n // Keep send button disabled if waiting for user to approve/reject further tool calls\n if (!aiService.hasToolCalls(answer)) {\n setIsSendButtonDisabled(false)\n }\n }\n\n const reject = () => {\n log.debug('ToolCallsApprove - Rejected', messagesRef.current)\n const currentMessages = messagesRef.current\n const dialogId = currentMessages[0]?.id\n if (dialogId) {\n aiService.rejectTools(dialogId, toolCalls)\n }\n const newMessages = removeApproveButtons([...currentMessages])\n newMessages.push(aiService.createUserMessage(username, 'Rejected'))\n updateConversations(newMessages)\n setIsSendButtonDisabled(false)\n }\n\n return (\n <Flex columnGap={{ default: 'columnGapSm' }}>\n <Button variant='primary' onClick={() => approve(toolCalls)}>\n Approve\n </Button>\n <Button variant='secondary' onClick={reject}>\n Reject\n </Button>\n </Flex>\n )\n}\n","import { PageContext } from '@hawtio/react/ui'\nimport Chatbot, { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'\nimport ChatbotContent from '@patternfly/chatbot/dist/dynamic/ChatbotContent'\nimport ChatbotConversationHistoryNav, {\n Conversation,\n} from '@patternfly/chatbot/dist/dynamic/ChatbotConversationHistoryNav'\nimport ChatbotFooter, { ChatbotFootnote } from '@patternfly/chatbot/dist/dynamic/ChatbotFooter'\nimport ChatbotHeader, {\n ChatbotHeaderActions,\n ChatbotHeaderCloseButton,\n ChatbotHeaderMain,\n ChatbotHeaderMenu,\n ChatbotHeaderTitle,\n} from '@patternfly/chatbot/dist/dynamic/ChatbotHeader'\nimport ChatbotWelcomePrompt from '@patternfly/chatbot/dist/dynamic/ChatbotWelcomePrompt'\nimport Message, { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport MessageBar from '@patternfly/chatbot/dist/dynamic/MessageBar'\nimport MessageBox from '@patternfly/chatbot/dist/dynamic/MessageBox'\nimport { Content, Label } from '@patternfly/react-core'\nimport React, { Dispatch, useContext, useEffect, useRef, useState } from 'react'\nimport { AIMessage } from '@langchain/core/messages'\nimport { aiService } from '../common/ai-service'\nimport { ChatbotContext } from './context'\nimport { log } from './globals'\nimport { ThinkInfo } from './ThinkInfo'\nimport { ToolCallsApprove } from './ToolCallsApprove'\nimport { ToolCallsInfo } from './ToolCallsInfo'\n\nexport const ChatbotPanel: React.FC<{\n title: string\n displayMode: ChatbotDisplayMode\n}> = ({ title, displayMode }) => {\n const { setMessages, dialogs, conversations } = useContext(ChatbotContext)\n const [isDrawerOpen, setIsDrawerOpen] = useState(false)\n const [filteredConversations, setFilteredConversations] = useState<Conversation[]>(conversations)\n\n const onSelectItemInHistory = (selected: string) => {\n log.debug('Selected conversation with ID:', selected)\n const dialog = dialogs.find(c => c.id === selected)\n if (dialog) {\n setMessages(dialog.messages)\n setIsDrawerOpen(false)\n }\n }\n\n const handleSearchTextChange = (value: string) => {\n if (value.trim() === '') {\n setFilteredConversations(conversations)\n return\n }\n\n const filtered = conversations.filter(c => c.text.toLowerCase().includes(value.toLowerCase()))\n log.debug('Filtered conversations:', filtered)\n setFilteredConversations(filtered)\n }\n\n return (\n <Chatbot isCompact displayMode={displayMode}>\n <ChatbotConversationHistoryNav\n isCompact\n drawerPanelContentProps={{ isResizable: true, minSize: '200px' }}\n displayMode={displayMode}\n onDrawerToggle={() => {\n setIsDrawerOpen(!isDrawerOpen)\n setFilteredConversations(conversations)\n }}\n isDrawerOpen={isDrawerOpen}\n setIsDrawerOpen={setIsDrawerOpen}\n onSelectActiveItem={(_e, selectedItem) => onSelectItemInHistory(String(selectedItem))}\n conversations={[...filteredConversations].reverse()}\n onNewChat={() => {\n setIsDrawerOpen(false)\n setFilteredConversations(conversations)\n setMessages([])\n }}\n handleTextInputChange={handleSearchTextChange}\n drawerContent={\n <>\n <ChatbotPanelHeader\n isDrawerOpen={isDrawerOpen}\n setIsDrawerOpen={setIsDrawerOpen}\n title={title}\n hasCloseButton={displayMode === ChatbotDisplayMode.drawer}\n />\n <ChatbotPanelContent />\n <ChatbotPanelFooter />\n </>\n }\n />\n </Chatbot>\n )\n}\n\nconst ChatbotPanelHeader: React.FC<{\n isDrawerOpen: boolean\n setIsDrawerOpen: Dispatch<React.SetStateAction<boolean>>\n title: string\n hasCloseButton: boolean\n}> = ({ isDrawerOpen, setIsDrawerOpen, title, hasCloseButton }) => {\n const { setIsChatbotOpen } = useContext(ChatbotContext)\n const modelName = aiService.getModel()?.name\n\n return (\n <ChatbotHeader>\n <ChatbotHeaderMain>\n <ChatbotHeaderMenu aria-expanded={isDrawerOpen} onMenuToggle={() => setIsDrawerOpen(!isDrawerOpen)} />\n <ChatbotHeaderTitle>\n <Content component='h2'>{title}</Content>\n </ChatbotHeaderTitle>\n </ChatbotHeaderMain>\n <ChatbotHeaderActions>\n {modelName && <Label variant='outline'>{modelName}</Label>}\n {hasCloseButton && <ChatbotHeaderCloseButton onClick={() => setIsChatbotOpen(false)} />}\n </ChatbotHeaderActions>\n </ChatbotHeader>\n )\n}\n\nconst ChatbotPanelContent: React.FC = () => {\n const { messages, announcement } = useContext(ChatbotContext)\n const { username } = useContext(PageContext)\n const scrollToBottomRef = useRef<HTMLDivElement>(null)\n\n const welcomeTitle = `Hello, ${username}!`\n const welcomeDescription = 'How can I help you manage or diagnose your Java application?'\n\n useEffect(() => {\n if (messages.length > 2) {\n scrollToBottomRef.current?.scrollIntoView({ behavior: 'smooth' })\n }\n }, [messages])\n\n return (\n <ChatbotContent>\n <MessageBox announcement={announcement}>\n {messages.length === 0 && <ChatbotWelcomePrompt title={welcomeTitle} description={welcomeDescription} />}\n {messages.map((message, index) => (\n <React.Fragment key={message.id}>\n {index === messages.length - 1 && <div ref={scrollToBottomRef} />}\n <Message key={message.id} {...message} />\n </React.Fragment>\n ))}\n </MessageBox>\n </ChatbotContent>\n )\n}\n\nconst ChatbotPanelFooter: React.FC = () => {\n const { username } = useContext(PageContext)\n const { messages, setAnnouncement, isSendButtonDisabled, setIsSendButtonDisabled, updateConversations } =\n useContext(ChatbotContext)\n const messagesRef = useRef(messages)\n\n useEffect(() => {\n messagesRef.current = messages\n }, [messages])\n\n const handleSend = async (message: string) => {\n if (!message.trim()) {\n return\n }\n log.debug('Send', messagesRef.current)\n\n setIsSendButtonDisabled(true)\n const newMessages: MessageProps[] = []\n newMessages.push(...messagesRef.current)\n newMessages.push(aiService.createUserMessage(username, message))\n newMessages.push(aiService.createLoadingBotMessage())\n updateConversations(newMessages)\n // make announcement to assistive devices that new messages have been added\n setAnnouncement(`Message from User: ${message}. Message from Bot is loading.`)\n log.debug('handleSend - new messages:', newMessages)\n\n const dialogId = newMessages[0]!.id!\n const loadedMessages: MessageProps[] = [...newMessages]\n\n const onMessage = (intermediateAnswer: AIMessage) => {\n // Remove loading, insert intermediate tool-calls message, re-add loading\n loadedMessages.pop()\n loadedMessages.push(aiService.toBotMessage(intermediateAnswer, true, ThinkInfo, ToolCallsInfo, ToolCallsApprove))\n loadedMessages.push(aiService.createLoadingBotMessage())\n updateConversations([...loadedMessages])\n }\n\n const answer = await (newMessages.length === 2\n ? aiService.newChat(dialogId, { message }, onMessage)\n : aiService.chat(dialogId, message, onMessage))\n log.debug('handleSend - loaded messages:', loadedMessages)\n // Remove the loading message, replace with the final bot message\n loadedMessages.pop()\n const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove)\n loadedMessages.push(botMessage)\n updateConversations([...loadedMessages])\n setAnnouncement(`Message from Bot: ${answer}`)\n // Keep send button disabled if waiting for user to approve/reject tool calls\n if (!aiService.hasToolCalls(answer)) {\n setIsSendButtonDisabled(false)\n }\n }\n\n return (\n <ChatbotFooter>\n <MessageBar\n onSendMessage={m => handleSend(String(m))}\n hasAttachButton={false}\n isSendButtonDisabled={isSendButtonDisabled}\n />\n <ChatbotFootnote label='AI may be inaccurate. Please verify important information.' />\n </ChatbotFooter>\n )\n}\n","import { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'\nimport { PageSection } from '@patternfly/react-core'\nimport React from 'react'\nimport './Chat.css'\nimport { ChatbotPanel } from './ChatbotPanel'\nimport { ChatbotContext, useChatbot } from './context'\n\nexport const Chat: React.FC = () => {\n const chatbotContext = useChatbot()\n\n return (\n <ChatbotContext.Provider value={chatbotContext}>\n <PageSection id='chat-content' hasBodyWrapper={false} isFilled padding={{ default: 'noPadding' }}>\n <ChatbotPanel title='AI Chat' displayMode={ChatbotDisplayMode.embedded} />\n </PageSection>\n </ChatbotContext.Provider>\n )\n}\n","export * from './Chat'\n","import { Logger } from '@hawtio/react'\n\nexport const pluginName = 'hawtio-ai-jmx'\nexport const pluginTitle = 'AI JMX'\nexport const pluginPath = '/ai-jmx'\n\nexport const log = Logger.get(pluginName)\n\nexport const PARAM_KEY_NODE_ID = 'nid'\n","import { EVENT_REFRESH, eventService, MBeanNode, MBeanTree, PluginNodeSelectionContext, workspace } from '@hawtio/react'\nimport { createContext, useContext, useEffect, useRef, useState } from 'react'\nimport { To, useNavigate, useSearchParams } from 'react-router'\nimport { log, PARAM_KEY_NODE_ID, pluginName, pluginPath } from './globals'\n\n/**\n * Custom React hook for using JMX MBean tree.\n */\nexport function useMBeanTree(): MBeanTreeContext {\n const [tree, setTree] = useState(MBeanTree.createEmpty(pluginName))\n const [loaded, setLoaded] = useState(false)\n const { selectedNode, setSelectedNode } = useContext(PluginNodeSelectionContext)\n const navigate = useNavigate()\n const [searchParams, setSearchParams] = useSearchParams()\n\n /*\n * Need to preserve the selected node between re-renders since the\n * populateTree function called via the refresh listener does not\n * cache the value and stores it as null\n */\n const refSelectedNode = useRef<MBeanNode | null>()\n refSelectedNode.current = selectedNode\n\n const populateTree = async () => {\n const wkspTree = await workspace.getTree()\n setTree(wkspTree)\n\n const nodeId = searchParams.get(PARAM_KEY_NODE_ID)\n if (nodeId && nodeId !== refSelectedNode.current?.id) {\n log.debug('Restore selected node with nid:', nodeId)\n // Try to restore node from URL\n const urlNode = wkspTree.find(node => node.id === nodeId)\n if (urlNode) {\n setSelectedNode(urlNode)\n refSelectedNode.current = urlNode\n } else {\n // Clear nid as it is invalid\n log.debug('Clear invalid nid:', nodeId)\n searchParams.delete(PARAM_KEY_NODE_ID)\n setSearchParams(searchParams)\n }\n }\n\n if (!refSelectedNode.current) return\n\n const path = [...refSelectedNode.current.path()]\n\n // Expand the nodes to redisplay the path\n wkspTree.forEach(path, node => {\n node.defaultExpanded = true\n })\n\n // Ensure the new version of the selected node is selected\n const newSelected = wkspTree.navigate(...path)\n if (newSelected) {\n setSelectedNode(newSelected)\n // Reset to base path with nid to sync URL with restored selection\n navigate(pluginPathWithNodeId(newSelected, searchParams))\n } else {\n // Node no longer exists - clear selection and go to base path\n navigate(pluginPath)\n }\n }\n\n useEffect(() => {\n const loadTree = async () => {\n await populateTree()\n setLoaded(true)\n }\n\n const listener = () => {\n setLoaded(false)\n loadTree()\n }\n eventService.onRefresh(listener)\n\n loadTree()\n\n return () => eventService.removeListener(EVENT_REFRESH, listener)\n }, [])\n\n return { tree, loaded, selectedNode, setSelectedNode }\n}\n\n/**\n * Build URL query string with nid parameter, preserving other existing params\n * @param node - The node to encode\n * @param searchParams - The current URL search params to preserve, defaults to the ones from the window location\n */\nexport function pluginPathWithNodeId(\n node: MBeanNode,\n searchParams: URLSearchParams = new URLSearchParams(window.location.search),\n): Partial<To> {\n searchParams.set(PARAM_KEY_NODE_ID, node.id)\n const query = `?${searchParams.toString()}`\n return { pathname: pluginPath, search: query }\n}\n\ntype MBeanTreeContext = {\n tree: MBeanTree\n loaded: boolean\n selectedNode: MBeanNode | null\n setSelectedNode: (selected: MBeanNode | null) => void\n}\n\nexport const MBeanTreeContext = createContext<MBeanTreeContext>({\n tree: MBeanTree.createEmpty(pluginName),\n loaded: false,\n selectedNode: null,\n setSelectedNode: () => {\n /* no-op */\n },\n})\n",".jmx-split {\n display: flex;\n flex-direction: row;\n height: calc(100vh - 85px);\n}\n\n.gutter {\n background-color: #eee;\n background-repeat: no-repeat;\n background-position: 50%;\n}\n\n.gutter.gutter-horizontal {\n background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');\n cursor: col-resize;\n}\n","#jmx-content {\n height: 100%;\n}\n\nsection#jmx-content-header.pf-v6-c-page__main-section {\n display: block;\n}\n\n#jmx-content-main > article {\n overflow: auto;\n}\n","import { AIMessage } from '@langchain/core/messages'\nimport { aiService } from '../common/ai-service'\n\nconst SYSTEM_MESSAGES = {\n diagnosis: `You are a helpful assistant diagnosing a JMX MBean based on its attribute values.\nGiven the following ObjectName and attribute values, identify any potential issues or anomalies.\nProvide suggestions for further investigation or resolution if applicable.\nRespond in a concise manner.`,\n} as const\n\nexport interface IJmxAiService {\n diagnoseMessage(objectName: string, attributes: string): string\n}\n\nclass JmxAiService implements IJmxAiService {\n systemMessage(): string {\n return SYSTEM_MESSAGES.diagnosis\n }\n\n diagnoseMessage(objectName: string, attributes: string): string {\n return `ObjectName:\n~~~\n${objectName}\n~~~\nAttribute values:\n~~~\n${attributes}\n~~~\nWhat potential issues or anomalies do you see?`\n }\n}\n\nexport const jmxAiService = new JmxAiService()\n","export function isObject(value: unknown): value is object {\n const type = typeof value\n return value != null && (type === 'object' || type === 'function')\n}\n\nexport function isNumber(value: unknown): value is number {\n return typeof value === 'number' && !Number.isNaN(value)\n}\n\nexport function stringSorter(a: string, b: string, sortDesc?: boolean): number {\n let res = a.localeCompare(b)\n if (sortDesc) {\n res *= -1\n }\n return res\n}\n\nexport function objectSorter(aValue: unknown, bValue: unknown, sortDesc?: boolean) {\n if (isNumber(aValue)) {\n // Numeric sort\n if (!sortDesc) {\n return (aValue as number) - (bValue as number)\n }\n return (bValue as number) - (aValue as number)\n } else {\n // String sort\n return stringSorter(aValue as string, bValue as string, sortDesc)\n }\n}\n\n/**\n * Return true if the string is either null or empty.\n */\nexport function isBlank(str?: string): boolean {\n if (str === undefined || str === null) {\n return true\n }\n if (typeof str !== 'string') {\n // not null but also not a string...\n return false\n }\n\n return str.trim().length === 0\n}\n\n/**\n * Will format a property to a standard human readable string with its spaces.\n * It will respect MBean and leave it together\n * @param str The property to transform\n * @returns The property with its proper spaces\n */\nexport function humanizeLabels(str: string): string {\n return str\n .split('-')\n .filter(str => !isBlank(str))\n .map(str => str.replace(/^./, str => str.toUpperCase()))\n .join(' ')\n .replace(/([a-z])([A-Z])/g, '$1 $2')\n .replace(/\\b([A-Z]+)([A-Z])([a-z])/, '$1 $2$3')\n .replace('M Bean', 'MBean')\n .replace('Mbean', 'MBean')\n .replace(/^./, str => str.toUpperCase())\n .replace(/ +/, ' ')\n .trim()\n}\n\n/**\n * Escapes the mbean for Jolokia GET requests.\n *\n * @param mbean the MBean\n */\nexport function escapeMBean(mbean: string): string {\n return encodeURI(applyJolokiaEscapeRules(mbean))\n}\n\n/**\n * Applies the Jolokia escaping rules to the MBean name.\n * See: https://jolokia.org/reference/html/manual/jolokia_protocol.html#_escaping_rules_in_get_requests\n *\n * @param mbean the MBean\n */\nfunction applyJolokiaEscapeRules(mbean: string): string {\n return mbean.replace(/!/g, '!!').replace(/\\//g, '!/').replace(/\"/g, '!\"')\n}\n","import { AttributeValues, eventService, jolokiaService } from '@hawtio/react'\nimport {\n JolokiaErrorResponse,\n JolokiaFetchErrorResponse,\n JolokiaRequest,\n JolokiaSuccessResponse,\n RequestOptions,\n} from 'jolokia.js'\nimport { log } from '../globals'\nimport { escapeMBean } from '../util'\n\nclass AttributeService {\n private handles: number[] = []\n\n private requestOptions(): RequestOptions {\n // serializeLong = false\n return {}\n }\n\n private setupConfig(request: JolokiaRequest): JolokiaRequest {\n // serializeLong = false\n return request\n }\n\n async read(mbean: string): Promise<AttributeValues> {\n return await jolokiaService.readAttributes(mbean, this.requestOptions())\n }\n\n async readWithCallback(mbean: string, callback: (attrs: AttributeValues) => void): Promise<void> {\n const attrs = await jolokiaService.readAttributes(mbean, this.requestOptions())\n callback(attrs)\n }\n\n async register(\n request: JolokiaRequest,\n callback: (response: JolokiaSuccessResponse | JolokiaErrorResponse | JolokiaFetchErrorResponse) => void,\n ) {\n const handle = await jolokiaService.register(this.setupConfig(request), callback)\n log.debug('Register handle:', handle)\n this.handles.push(handle)\n }\n\n unregisterAll() {\n log.debug('Unregister all handles:', this.handles)\n this.handles.forEach(handle => jolokiaService.unregister(handle))\n this.handles = []\n }\n\n async buildUrl(mbean: string, attribute: string): Promise<string> {\n const jolokiaUrl = await jolokiaService.getFullJolokiaUrl()\n return `${jolokiaUrl}/read/${escapeMBean(mbean)}/${attribute}`\n }\n\n async canInvoke(mbean: string, attribute: string, type: string): Promise<boolean> {\n return true\n /*\n const aclMBean = await rbacService.getACLMBean()\n if (!aclMBean) {\n // Always allow invocation when client-side RBAC is not available\n return true\n }\n\n const operation = 'canInvoke(java.lang.String,java.lang.String,[Ljava.lang.String;)'\n const args = [mbean, `set${attribute}`, [type]]\n return jolokiaService.execute(aclMBean, operation, args) as Promise<boolean>\n */\n }\n\n async update(mbeanName: string, attribute: string, value: unknown) {\n await jolokiaService.writeAttribute(mbeanName, attribute, value, this.requestOptions())\n eventService.notify({ type: 'success', message: `Updated attribute: ${attribute}` })\n }\n\n async bulkRequest(requests: JolokiaRequest[]) {\n return jolokiaService.bulkRequest(requests.map(this.setupConfig))\n }\n}\n\nexport const attributeService = new AttributeService()\n","import { AttributeModal, AttributeValues, HawtioEmptyCard, HawtioLoadingCard } from '@hawtio/react'\nimport { PageContext } from '@hawtio/react/ui'\nimport { MessageProps } from '@patternfly/chatbot/dist/dynamic/Message'\nimport {\n Button,\n Drawer,\n DrawerContent,\n DrawerContentBody,\n Panel,\n Toolbar,\n ToolbarContent,\n ToolbarItem,\n} from '@patternfly/react-core'\nimport { MonitoringIcon } from '@patternfly/react-icons'\nimport { Table, Tbody, Td, Th, Thead, ThProps, Tr } from '@patternfly/react-table'\nimport Jolokia, { JolokiaErrorResponse, JolokiaFetchErrorResponse, JolokiaSuccessResponse } from 'jolokia.js'\nimport React, { useContext, useEffect, useState } from 'react'\nimport { ChatbotContext } from '../../chat/context'\nimport { ThinkInfo } from '../../chat/ThinkInfo'\nimport { ToolCallsApprove } from '../../chat/ToolCallsApprove'\nimport { ToolCallsInfo } from '../../chat/ToolCallsInfo'\nimport { aiService } from '../../common/ai-service'\nimport { MBeanTreeContext } from '../context'\nimport { log } from '../globals'\nimport { jmxAiService } from '../jmx-ai-service'\nimport { isObject, objectSorter } from '../util'\nimport { attributeService } from './attribute-service'\n\nexport const Attributes: React.FC = () => {\n const { selectedNode } = useContext(MBeanTreeContext)\n const [attributes, setAttributes] = useState<AttributeValues>({})\n const [isReading, setIsReading] = useState(true)\n const [isModalOpen, setIsModalOpen] = useState(false)\n const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc')\n const [selected, setSelected] = useState({ name: '', value: '' })\n const [reload, setReload] = useState(false)\n\n useEffect(() => {\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {\n return\n }\n\n setIsReading(true)\n const { objectName } = selectedNode\n attributeService.readWithCallback(objectName, attrs => {\n setAttributes(attrs)\n setIsReading(false)\n })\n\n attributeService.register(\n { type: 'read', mbean: objectName },\n (response: JolokiaSuccessResponse | JolokiaErrorResponse | JolokiaFetchErrorResponse) => {\n if (response && !Jolokia.isError(response as JolokiaSuccessResponse | JolokiaErrorResponse)) {\n setAttributes((response as JolokiaSuccessResponse).value as AttributeValues)\n }\n },\n )\n\n return () => attributeService.unregisterAll()\n }, [selectedNode])\n\n useEffect(() => {\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName || !reload) {\n return\n }\n\n setIsReading(true)\n const { objectName } = selectedNode\n attributeService.readWithCallback(objectName, attrs => {\n setAttributes(attrs)\n setIsReading(false)\n })\n\n setReload(false)\n }, [selectedNode, reload])\n\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {\n return null\n }\n\n if (isReading) {\n return <HawtioLoadingCard />\n }\n\n const rows: { name: string; value: string }[] = Object.entries(attributes).map(([name, value]) => ({\n name: name,\n value: isObject(value) ? JSON.stringify(value) : String(value),\n }))\n\n if (rows.length === 0) {\n return <HawtioEmptyCard message='This MBean has no attributes.' />\n }\n\n const selectAttribute = (attribute: { name: string; value: string }) => {\n setSelected(attribute)\n if (!isModalOpen) {\n setIsModalOpen(true)\n }\n }\n\n const getSortParams = (): ThProps['sort'] => ({\n sortBy: {\n index: 0,\n direction: sortDirection,\n defaultDirection: 'asc', // starting sort direction when first sorting a column. Defaults to 'asc'\n },\n onSort: (_event, _index, direction) => {\n setSortDirection(direction)\n },\n columnIndex: 0,\n })\n\n const panelContent = (\n <AttributeModal\n isOpen={isModalOpen}\n onClose={() => setIsModalOpen(false)}\n onUpdate={() => setReload(true)}\n input={selected}\n />\n )\n\n const attributesTable = (\n <div id='attribute-table-with-panel'>\n <AiJmxToolbar attributes={attributes} />\n <Table aria-label='Attributes' variant='compact'>\n <Thead>\n <Tr>\n <Th sort={getSortParams()}>Attribute</Th>\n <Th>Value</Th>\n </Tr>\n </Thead>\n <Tbody>\n {rows\n .sort((a, b) => objectSorter(a.name, b.name, sortDirection === 'desc'))\n .map((att, index) => (\n <Tr\n key={att.name + '-' + index}\n isClickable\n isRowSelected={selected.name === att.name}\n onRowClick={() => selectAttribute(att)}\n >\n <Td>{att.name}</Td>\n <Td>{att.value}</Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </div>\n )\n\n return (\n <Panel>\n <Drawer isExpanded={isModalOpen} className='pf-m-inline-on-2xl'>\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody hasPadding>{attributesTable}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n </Panel>\n )\n}\n\nconst AiJmxToolbar: React.FC<{\n attributes: AttributeValues\n}> = ({ attributes }) => {\n const { selectedNode } = useContext(MBeanTreeContext)\n const { username } = useContext(PageContext)\n const { setAnnouncement, setIsChatbotOpen, updateConversations } = useContext(ChatbotContext)\n\n if (!selectedNode || !selectedNode.mbean || !selectedNode.objectName) {\n return null\n }\n const { objectName } = selectedNode\n\n const diagnose = async () => {\n setIsChatbotOpen(true)\n const attrsValue = JSON.stringify(attributes)\n log.debug('Attributes:', attrsValue)\n\n const systemMessage = jmxAiService.systemMessage()\n const diagnoseMessage = jmxAiService.diagnoseMessage(objectName, attrsValue)\n const newMessages: MessageProps[] = []\n newMessages.push(aiService.createUserMessage(username, diagnoseMessage))\n newMessages.push(aiService.createLoadingBotMessage())\n updateConversations(newMessages, `Diagnose ${objectName}`)\n setAnnouncement('Diagnosis in progress...')\n log.debug('diagnose - new messages:', newMessages)\n\n const dialogId = newMessages[0]!.id!\n const answer = await aiService.newChat(dialogId, { message: diagnoseMessage, system: systemMessage })\n const loadedMessages: MessageProps[] = []\n loadedMessages.push(...newMessages)\n log.debug('diagnose - loaded messages:', loadedMessages)\n // Remove the loading message\n loadedMessages.pop()\n const botMessage = aiService.toBotMessage(answer, false, ThinkInfo, ToolCallsInfo, ToolCallsApprove)\n loadedMessages.push(botMessage)\n updateConversations(loadedMessages)\n setAnnouncement('Diagnosis complete.')\n }\n\n return (\n <Toolbar id='ai-jmx-toolbar'>\n <ToolbarContent>\n <ToolbarItem>\n <Button variant='primary' size='sm' icon={<MonitoringIcon />} onClick={diagnose}>\n Diagnose\n </Button>\n </ToolbarItem>\n </ToolbarContent>\n </Toolbar>\n )\n}\n","export { Attributes } from './Attributes'\n","import { AttributeTable, Chart, JmxContentMBeans, MBeanNode, Operations } from '@hawtio/react'\nimport { ChatbotDisplayMode } from '@patternfly/chatbot/dist/dynamic/Chatbot'\nimport {\n Button,\n Content,\n Drawer,\n DrawerContent,\n DrawerContentBody,\n DrawerPanelBody,\n DrawerPanelContent,\n EmptyState,\n Nav,\n NavItem,\n NavList,\n PageGroup,\n PageSection,\n Title,\n Toolbar,\n ToolbarItem,\n} from '@patternfly/react-core'\nimport { right } from '@patternfly/react-core/dist/esm/helpers/Popper/thirdparty/popper-core'\nimport { CubesIcon } from '@patternfly/react-icons/dist/esm/icons/cubes-icon'\nimport React, { useContext, useRef } from 'react'\nimport { Navigate, NavLink, Route, Routes, useLocation } from 'react-router'\nimport { ChatbotPanel } from '../chat/ChatbotPanel'\nimport { ChatbotContext, useChatbot } from '../chat/context'\nimport './JmxContent.css'\nimport { Attributes } from './attributes'\nimport { MBeanTreeContext, pluginPathWithNodeId } from './context'\nimport { pluginPath } from './globals'\n\nexport const JmxContent: React.FunctionComponent = () => {\n const { selectedNode } = useContext(MBeanTreeContext)\n const { pathname, search } = useLocation()\n const chatbotContext = useChatbot()\n const { isChatbotOpen, setIsChatbotOpen } = chatbotContext\n const drawerRef = useRef<HTMLDivElement>(undefined)\n\n if (!selectedNode) {\n return (\n <PageSection hasBodyWrapper={false} isFilled>\n <EmptyState headingLevel='h1' icon={CubesIcon} titleText='Select MBean' variant='full' />\n </PageSection>\n )\n }\n\n const mBeanApplicable = (node: MBeanNode) => Boolean(node.objectName)\n const mBeanCollectionApplicable = (node: MBeanNode) => Boolean(node.children?.every(child => child.objectName))\n const hasAnyApplicableMBean = (node: MBeanNode) =>\n Boolean(node.objectName) || Boolean(node.children?.some(child => child.objectName))\n\n const tableSelector = (node: MBeanNode) => {\n const tablePriorityList = [\n { condition: mBeanApplicable, element: Attributes },\n { condition: mBeanCollectionApplicable, element: AttributeTable },\n ]\n\n return tablePriorityList.find(entry => entry.condition(node))?.element ?? JmxContentMBeans\n }\n\n const allNavItems = [\n { id: 'attributes', title: 'Attributes', component: tableSelector(selectedNode), isApplicable: () => true },\n { id: 'operations', title: 'Operations', component: Operations, isApplicable: mBeanApplicable },\n { id: 'chart', title: 'Chart', component: Chart, isApplicable: hasAnyApplicableMBean },\n ]\n\n /* Filter the nav items to those applicable to the selected node */\n const navItems = allNavItems.filter(nav => nav.isApplicable(selectedNode))\n\n const searchWithNid = (pluginPathWithNodeId(selectedNode, new URLSearchParams(search)) as { search: string }).search\n\n const mbeanNav = (\n <Nav aria-label='MBean Nav' variant='horizontal-subnav'>\n <NavList>\n {navItems.map(nav => (\n <NavItem key={nav.id} isActive={pathname === `${pluginPath}/${nav.id}`}>\n <NavLink to={{ pathname: nav.id, search }}>{nav.title}</NavLink>\n </NavItem>\n ))}\n </NavList>\n </Nav>\n )\n\n const mbeanRoutes = navItems.map(nav => (\n <Route key={nav.id} path={nav.id} element={React.createElement(nav.component)} />\n ))\n\n const jmxAiToolbar = (\n <Toolbar id='jmx-ai-toolbar' style={{ float: right }}>\n <ToolbarItem>\n <Button variant='secondary' size='sm' onClick={() => setIsChatbotOpen(!isChatbotOpen)}>\n Chat\n </Button>\n </ToolbarItem>\n </Toolbar>\n )\n\n const jmxContent = (\n <PageGroup id='jmx-content'>\n <PageSection id='jmx-content-header' hasBodyWrapper={false}>\n {jmxAiToolbar}\n <Title headingLevel='h1'>{selectedNode.name}</Title>\n <Content component='small'>{selectedNode.objectName}</Content>\n </PageSection>\n <PageSection type='tabs' hasBodyWrapper={false}>\n {mbeanNav}\n </PageSection>\n <PageSection\n id='jmx-content-main'\n padding={{ default: 'noPadding' }}\n hasOverflowScroll\n aria-label='jmx-content-main'\n hasBodyWrapper={false}\n >\n <Routes>\n {mbeanRoutes}\n <Route\n key='root'\n path='/'\n element={<Navigate to={{ pathname: navItems[0]?.id ?? '', search: searchWithNid }} />}\n />\n </Routes>\n </PageSection>\n </PageGroup>\n )\n\n const onDrawerExpand = () => {\n drawerRef.current && drawerRef.current.focus()\n }\n\n const panelContent = (\n <DrawerPanelContent isResizable defaultSize='500px' minSize='200px'>\n <DrawerPanelBody>\n <ChatbotPanel title='AI Diagnosis' displayMode={ChatbotDisplayMode.drawer} />\n </DrawerPanelBody>\n </DrawerPanelContent>\n )\n\n return (\n <ChatbotContext.Provider value={chatbotContext}>\n <Drawer isExpanded={isChatbotOpen} isInline onExpand={onDrawerExpand}>\n <DrawerContent panelContent={panelContent}>\n <DrawerContentBody>{jmxContent}</DrawerContentBody>\n </DrawerContent>\n </Drawer>\n </ChatbotContext.Provider>\n )\n}\n","#jmx-tree-view.pf-v6-c-tree-view {\n --pf-v6-c-tree-view__node--indent--base: 1rem;\n --pf-v6-c-tree-view__node--nested-indent--base: 1rem;\n --pf-v6-c-tree-view--m-guides__node--before--Width: 1.25rem;\n --pf-v6-c-tree-view--m-guides__node--before--Height: 1px;\n --pf-v6-c-tree-view--m-guides__node--before--InsetBlockStart: 0.625rem;\n --pf-v6-c-tree-view--m-guides__node--before--BackgroundColor: var(--pf-t--global--border--color--default);\n --pf-v6-c-tree-view--m-guides__list-item--before--Width: 1px;\n --pf-v6-c-tree-view--m-guides__list-item--before--Height: 100%;\n --pf-v6-c-tree-view--m-guides__list-item--before--BackgroundColor: var(--pf-t--global--border--color--default);\n --pf-v6-c-tree-view--m-guides__list-item--last-child--before--Height: 0.68rem;\n --pf-v6-c-tree-view--m-guides__list-node--guide-width--base: 0.5rem;\n --pf-v6-c-tree-view--m-guides--guide-left--base--offset: 1.4rem;\n}\n#jmx-tree-view.pf-v6-c-tree-view .pf-m-selectable {\n --pf-v6-c-tree-view--m-guides__node--before--Width: 0.5rem;\n}\n#jmx-tree-view .pf-v6-c-tree-view__list {\n height: 100%;\n}\n\n#jmx-tree-view > .pf-v6-c-tree-view__list {\n max-height: 83vh;\n overflow: auto;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node {\n padding-top: 0;\n padding-bottom: 0;\n align-items: center;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node:has(button.pf-v6-c-tree-view__node-toggle) {\n --pf-v6-c-tree-view--m-guides__node--before--Width: 0.5rem;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-toggle {\n padding: 0;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-text {\n padding: 0 4px;\n font-size: small;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-icon {\n padding: 0 4px;\n flex-shrink: 0;\n}\n\n#jmx-tree-view .pf-v6-c-tree-view__node-text {\n overflow-x: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n","import { MBeanNode, MBeanTree, PluginTreeViewToolbar } from '@hawtio/react'\nimport { TreeView, TreeViewDataItem } from '@patternfly/react-core'\nimport React, { ChangeEvent, useContext, useEffect, useState } from 'react'\nimport { useNavigate } from 'react-router'\nimport './JmxTreeView.css'\nimport { MBeanTreeContext, pluginPathWithNodeId } from './context'\n\n/**\n * Expansion requires more than 2 states since the expandAll\n * must be removed completely to defer to the expanded state\n * of each data node\n */\nenum ExpansionValue {\n /**\n * should revert to the expanded state of the data\n */\n Default,\n /**\n * all data should be expanded\n */\n ExpandAll,\n /**\n * all data should be collapsed\n */\n CollapseAll,\n}\n\nexport const JmxTreeView: React.FunctionComponent = () => {\n const { tree, selectedNode, setSelectedNode } = useContext(MBeanTreeContext)\n const [expanded, setExpanded] = useState(ExpansionValue.Default)\n const [filteredTree, setFilteredTree] = useState(tree.getTree())\n const navigate = useNavigate()\n\n /**\n * Listen for changes to the tree that may occur as a result\n * of events being monitored by the Tree:Watcher in workspace\n * eg. new endpoint being created\n */\n useEffect(() => {\n setFilteredTree(tree.getTree())\n }, [tree])\n\n const onSearch = (event: ChangeEvent<HTMLInputElement>) => {\n // Ensure no node from the 'old' filtered is lingering\n setSelectedNode(null)\n setExpanded(ExpansionValue.Default)\n const input = event.target.value\n\n if (!input) setFilteredTree(tree.getTree())\n\n const treeElements = MBeanTree.filter(tree.getTree(), node => node.name.toLowerCase().includes(input.toLowerCase()))\n\n if (treeElements.length === 0) setFilteredTree(tree.getTree())\n else {\n setFilteredTree(treeElements)\n setExpanded(ExpansionValue.ExpandAll)\n }\n }\n\n const onSelect = (event: React.MouseEvent<Element, MouseEvent>, item: TreeViewDataItem) => {\n const node = item as MBeanNode\n setSelectedNode(node)\n navigate(pluginPathWithNodeId(node))\n }\n\n const setAllExpanded = (value: boolean) => {\n setExpanded(value ? ExpansionValue.ExpandAll : ExpansionValue.CollapseAll)\n }\n\n const expandedProp = (): object => {\n switch (expanded) {\n case ExpansionValue.ExpandAll:\n return { allExpanded: true }\n case ExpansionValue.CollapseAll:\n return { allExpanded: false }\n default:\n return {}\n }\n }\n\n return (\n <TreeView\n id='jmx-tree-view'\n data={filteredTree}\n hasGuides={true}\n hasSelectableNodes={true}\n activeItems={selectedNode ? [selectedNode] : []}\n {...expandedProp()}\n onSelect={onSelect}\n toolbar={<PluginTreeViewToolbar onSearch={onSearch} onSetExpanded={setAllExpanded} />}\n />\n )\n}\n","import { EmptyState, PageSection, Spinner } from '@patternfly/react-core'\nimport { CubesIcon } from '@patternfly/react-icons/dist/esm/icons/cubes-icon'\nimport React from 'react'\nimport Split from 'react-split'\nimport { MBeanTreeContext, useMBeanTree } from './context'\nimport './Jmx.css'\nimport { JmxContent } from './JmxContent'\nimport { JmxTreeView } from './JmxTreeView'\n\nexport const Jmx: React.FunctionComponent = () => {\n const { tree, loaded, selectedNode, setSelectedNode } = useMBeanTree()\n\n if (!loaded) {\n return (\n <PageSection hasBodyWrapper={false}>\n <Spinner aria-label='Loading MBean tree' />\n </PageSection>\n )\n }\n\n if (tree.isEmpty()) {\n return (\n <PageSection hasBodyWrapper={false}>\n <EmptyState headingLevel='h1' icon={CubesIcon} titleText='No MBeans found' variant='full' />\n </PageSection>\n )\n }\n\n return (\n <MBeanTreeContext.Provider value={{ tree, loaded, selectedNode, setSelectedNode }}>\n <Split className='jmx-split' sizes={[30, 70]} minSize={200} gutterSize={5}>\n <div>\n <JmxTreeView />\n </div>\n <div>\n <JmxContent />\n </div>\n </Split>\n </MBeanTreeContext.Provider>\n )\n}\n","export * from './Jmx'\nexport * from './JmxContent'\nexport * from './JmxTreeView'\n","import { HawtioPlugin, configManager } from '@hawtio/react'\nimport '@patternfly/chatbot/dist/css/main.css'\nimport { aiChat } from './chat'\nimport { aiCommon } from './common'\nimport { aiJmx } from './jmx-ai'\n\n/**\n * The entry function for the plugin exposed to Hawtio.\n *\n * The default name for the function is \"plugin\". If you want to use the name other\n * than the default one, you need to specify the name using {HawtioPlugin#setPluginEntry()}\n * method when registering the plugin to JMX MBean server.\n *\n * <code>\n * HawtioPlugin plugin = new HawtioPlugin();\n * plugin.setPluginEntry(\"registerMyPlugin\");\n * </code>\n *\n * @see src/main/java/io/hawt/example/spring/boot/SampleSpringBootService.java\n */\nexport const plugin: HawtioPlugin = () => {\n aiCommon()\n aiJmx()\n aiChat()\n}\n\n// Register the custom plugin version to Hawtio\n// See package.json \"replace-version\" script for how to replace the version placeholder with a real version\nconfigManager.addProductInfo('Hawtio AI Plugin', '__PACKAGE_VERSION_PLACEHOLDER__')\n","import { hawtio, type HawtioPlugin } from '@hawtio/react'\nimport { log, pluginName, pluginPath, pluginTitle } from './globals'\n\nconst order = 42\n\nexport const aiChat: HawtioPlugin = () => {\n log.info('Loading', pluginName)\n\n hawtio.addDeferredPlugin(pluginName, async () => {\n return import('./ui').then(({ Chat }) => {\n return {\n id: pluginName,\n title: pluginTitle,\n path: pluginPath,\n order,\n component: Chat,\n isActive: async () => true,\n }\n })\n })\n}\n","import { HawtioPlugin, preferencesRegistry } from '@hawtio/react'\nimport { AiPreferences } from '../common/AiPreferences'\nimport { pluginName, pluginTitle } from './globals'\n\nconst order = 40\n\nexport const aiCommon: HawtioPlugin = () => {\n preferencesRegistry.add(pluginName, pluginTitle, AiPreferences, order)\n}\n","import {\n Button,\n CardBody,\n Content,\n Form,\n FormGroup,\n FormSection,\n FormSelect,\n FormSelectOption,\n InputGroup,\n InputGroupItem,\n NumberInput,\n Switch,\n TextInput,\n} from '@patternfly/react-core'\nimport EyeIcon from '@patternfly/react-icons/dist/esm/icons/eye-icon'\nimport EyeSlashIcon from '@patternfly/react-icons/dist/esm/icons/eye-slash-icon'\nimport { Table, Tbody, Td, Th, Thead, Tr } from '@patternfly/react-table'\nimport React, { useState } from 'react'\nimport { MODELS, PROVIDERS } from './ai-model'\nimport {\n AiOptions,\n DEFAULT_MAX_AUTO_TOOL_STEPS,\n DEFAULT_TOOL_PERMISSIONS,\n aiPreferencesService,\n} from './ai-preferences-service'\nimport './AiPreferences.css'\nimport { WORKSPACE_TOOLS_META } from './tools'\n\nexport const AiPreferences: React.FC = () => {\n const [options, setOptions] = useState(aiPreferencesService.loadOptions())\n\n return (\n <CardBody>\n <Form id='ai-prefs-form' isHorizontal>\n <ModelForm options={options} setOptions={setOptions} />\n <PermissionForm options={options} setOptions={setOptions} />\n </Form>\n </CardBody>\n )\n}\n\nconst ModelForm: React.FC<{\n options: AiOptions\n setOptions: React.Dispatch<React.SetStateAction<AiOptions>>\n}> = ({ options, setOptions }) => {\n const [provider, setProvider] = useState<string>(options.model.provider)\n const [models, setModels] = useState(MODELS.filter(m => m.provider === provider))\n const [passwordHidden, setPasswordHidden] = useState(true)\n\n const updateProvider = (provider: string) => {\n setProvider(provider)\n const models = MODELS.filter(m => m.provider === provider)\n setModels(models)\n // Set the first model for the selected provider\n updateModel(models[0]!.id)\n }\n\n const updateModel = (updated: string) => {\n const model = MODELS.find(m => m.id === updated)\n if (model) {\n aiPreferencesService.saveOptions({ model })\n setOptions({ ...options, model })\n }\n }\n\n const updateToken = (updated?: string) => {\n aiPreferencesService.saveOptions({ token: updated })\n setOptions({ ...options, token: updated })\n }\n\n return (\n <FormSection title='Model' titleElement='h2'>\n <FormGroup fieldId='ai-prefs-form-provider' label='Provider'>\n <FormSelect\n id='ai-prefs-form-provider-input'\n aria-label='Form Select Provider'\n value={provider}\n onChange={(_, p) => updateProvider(p)}\n >\n {PROVIDERS.map((p, i) => (\n <FormSelectOption key={i} value={p} label={p} />\n ))}\n </FormSelect>\n </FormGroup>\n <FormGroup fieldId='ai-prefs-form-model' label='Model'>\n <FormSelect\n id='ai-prefs-form-model-input'\n aria-label='Form Select Model'\n value={options.model.id}\n onChange={(_, id) => updateModel(id)}\n >\n {models.map(m => (\n <FormSelectOption key={m.id} value={m.id} label={m.name} />\n ))}\n </FormSelect>\n </FormGroup>\n <FormGroup fieldId='ai-prefs-form-token' label='API Key / Token (optional)'>\n <InputGroup>\n <InputGroupItem isFill>\n <TextInput\n id='ai-prefs-form-token-input'\n aria-label='Form Select Token'\n type={passwordHidden ? 'password' : 'text'}\n value={options.token}\n onChange={(_, t) => updateToken(t)}\n />\n </InputGroupItem>\n <InputGroupItem>\n <Button\n variant='control'\n onClick={() => setPasswordHidden(!passwordHidden)}\n aria-label={passwordHidden ? 'Show password' : 'Hide password'}\n >\n {passwordHidden ? <EyeIcon /> : <EyeSlashIcon />}\n </Button>\n </InputGroupItem>\n </InputGroup>\n </FormGroup>\n </FormSection>\n )\n}\n\nconst PermissionForm: React.FC<{\n options: AiOptions\n setOptions: React.Dispatch<React.SetStateAction<AiOptions>>\n}> = ({ options, setOptions }) => {\n const maxAutoToolSteps = options.maxAutoToolSteps ?? DEFAULT_MAX_AUTO_TOOL_STEPS\n const toolPermissions = options.toolPermissions ?? DEFAULT_TOOL_PERMISSIONS\n\n const updateMaxAutoToolSteps = (updated: number) => {\n aiPreferencesService.saveOptions({ maxAutoToolSteps: updated })\n setOptions({ ...options, maxAutoToolSteps: updated })\n }\n\n const updatePermission = (tool: string, updated: boolean) => {\n const updatedPermissions = { ...toolPermissions, [tool]: updated }\n aiPreferencesService.saveOptions({ toolPermissions: updatedPermissions })\n setOptions({ ...options, toolPermissions: updatedPermissions })\n }\n\n return (\n <FormSection title='Permission control' titleElement='h2'>\n <FormGroup fieldId='ai-prefs-form-max-steps' label='Max auto-approve steps'>\n <NumberInput\n id='ai-prefs-form-max-steps-input'\n aria-label='Form select max auto-approve steps'\n value={options.maxAutoToolSteps}\n min={1}\n max={100}\n onMinus={() => updateMaxAutoToolSteps(Math.max(1, maxAutoToolSteps - 1))}\n onPlus={() => updateMaxAutoToolSteps(Math.min(100, maxAutoToolSteps + 1))}\n onChange={e => {\n const value = parseInt((e.target as HTMLInputElement).value)\n if (!isNaN(value) && value >= 1 && value <= 100) {\n updateMaxAutoToolSteps(value)\n }\n }}\n />\n </FormGroup>\n <FormGroup fieldId='ai-prefs-form-tool-permissions' style={{ display: 'flex' }}>\n <Content component='small'>\n Enable auto-approve to allow a tool to run without asking for confirmation each time.\n </Content>\n <Table\n aria-label='Tool permissions'\n variant='compact'\n borders={false}\n isStriped\n isStickyHeader\n style={{ marginTop: '0.5rem' }}\n >\n <Thead>\n <Tr>\n <Th modifier='fitContent'>Tool</Th>\n <Th modifier='wrap'>Description</Th>\n <Th modifier='fitContent'>Auto-approve</Th>\n </Tr>\n </Thead>\n <Tbody>\n {WORKSPACE_TOOLS_META.map(({ name, description }) => (\n <Tr key={name}>\n <Td dataLabel='Tool'>\n <b>{name}</b>\n </Td>\n <Td dataLabel='Description'>{description}</Td>\n <Td dataLabel='Auto-approve' textCenter>\n <Switch\n id={`ai-prefs-tool-switch-${name}`}\n aria-label={`Auto-approve ${name}`}\n isChecked={toolPermissions[name] ?? false}\n onChange={(_, checked) => updatePermission(name, checked)}\n />\n </Td>\n </Tr>\n ))}\n </Tbody>\n </Table>\n </FormGroup>\n </FormSection>\n )\n}\n","import { hawtio, helpRegistry, workspace, type HawtioPlugin } from '@hawtio/react'\nimport { log, pluginName, pluginPath, pluginTitle } from './globals'\nimport help from './help.md'\n\nconst order = 41\n\nexport const aiJmx: HawtioPlugin = () => {\n log.info('Loading', pluginName)\n\n hawtio.addDeferredPlugin(pluginName, async () => {\n return import('./ui').then(({ Jmx }) => {\n return {\n id: pluginName,\n title: pluginTitle,\n path: pluginPath,\n order,\n component: Jmx,\n knownQueryParams: ['nid'],\n isActive: async () => workspace.hasMBeans(),\n }\n })\n })\n helpRegistry.add(pluginName, pluginTitle, help, order)\n}\n","# 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"],"mappings":"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","names":["import_react","pluginName","pluginTitle","log","init_globals","import_react","init_globals","workspace","jolokiaService","log","log","import_react","init_globals","import_react","init_globals","log","userAvatar","botAvatar","ThinkInfo","ToolCallsInfo","ToolCallsApprove","content","messages","import_react","MarkdownContent","import_react_core","import_jsx_runtime","WrenchIcon","import_react_core","import_react","import_jsx_runtime","messages","toolCalls","import_ui","import_react_core","import_react","import_jsx_runtime","Chatbot","ChatbotConversationHistoryNav","ChatbotHeader","ChatbotContent","MessageBox","ChatbotWelcomePrompt","React","Message","ChatbotFooter","MessageBar","import_Chatbot","import_react_core","import_jsx_runtime","init_Chat","init_Chat","import_react","pluginName","pluginTitle","pluginPath","log","init_globals","pluginName","log","pluginPath","import_react","init_context","init_globals","import_react","init_globals","log","import_react","import_ui","import_react_core","import_react_table","import_jsx_runtime","init_context","init_globals","Jolokia","log","import_react","import_Chatbot","import_react_core","import_react_router","import_jsx_runtime","init_JmxContent","init_context","init_globals","pluginPath","React","import_react","import_react_core","import_react_router","import_jsx_runtime","init_JmxTreeView","init_context","import_react_core","import_cubes_icon","import_jsx_runtime","init_Jmx","init_context","init_JmxContent","init_JmxTreeView","Split","ui_exports","init_ui","init_Jmx","init_JmxContent","init_JmxTreeView","import_react","import_react","Chat","import_react","import_react_core","import_react","import_jsx_runtime","provider","models","EyeIcon","EyeSlashIcon","init_globals","order","pluginName","pluginTitle","import_react","init_globals","order","log","pluginName","Jmx","pluginTitle","pluginPath"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hawtio/ai-plugin",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Hawtio AI plugin",
5
5
  "main": "./dist/index.js",
6
6
  "license": "Apache-2.0",