@hawtio/ai-plugin 0.1.1 → 0.1.6
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 +21 -0
- package/dist/index.js +114 -57
- package/dist/index.js.map +1 -1
- package/package.json +8 -6
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,27 @@
|
|
|
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.1.6](///compare/v0.1.5...v0.1.6) (2026-05-01)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* make attribute modal open automatically after diagnosis finished 06725b6
|
|
11
|
+
|
|
12
|
+
## [0.1.5](///compare/v0.1.1...v0.1.5) (2026-05-01)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* add support for OpenAI & Anthropic models 306638d, closes #10
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
### Bug Fixes
|
|
21
|
+
|
|
22
|
+
* exclude test app from releasing 5c107bd
|
|
23
|
+
* skip publishing test app (finally) 2bb437e
|
|
24
|
+
* skip test app deployment (again) 2209659
|
|
25
|
+
|
|
5
26
|
## [0.1.1](///compare/v0.1.0...v0.1.1) (2026-04-23)
|
|
6
27
|
|
|
7
28
|
|
package/dist/index.js
CHANGED
|
@@ -2055,8 +2055,9 @@ function extractMethod(request, params) {
|
|
|
2055
2055
|
method = "get";
|
|
2056
2056
|
} else if (methodGiven !== "post") {
|
|
2057
2057
|
throw new Error('Illegal method "' + methodGiven + '"');
|
|
2058
|
+
} else {
|
|
2059
|
+
method = "post";
|
|
2058
2060
|
}
|
|
2059
|
-
method = "post";
|
|
2060
2061
|
} else {
|
|
2061
2062
|
if (Array.isArray(request) || "config" in request || request.type?.toLowerCase() === "read" && "attribute" in request && Array.isArray(request.attribute) || "target" in request) {
|
|
2062
2063
|
method = "post";
|
|
@@ -2145,7 +2146,7 @@ var CLIENT_VERSION, DEFAULT_FETCH_PARAMS, PROCESSING_PARAMS, Jolokia, GET_URL_EX
|
|
|
2145
2146
|
var init_jolokia = __esm({
|
|
2146
2147
|
"node_modules/jolokia.js/dist/jolokia.mjs"() {
|
|
2147
2148
|
"use strict";
|
|
2148
|
-
CLIENT_VERSION = "2.
|
|
2149
|
+
CLIENT_VERSION = "2.6.0";
|
|
2149
2150
|
DEFAULT_FETCH_PARAMS = {
|
|
2150
2151
|
cache: "no-store",
|
|
2151
2152
|
credentials: "same-origin",
|
|
@@ -2549,21 +2550,33 @@ var init_jolokia = __esm({
|
|
|
2549
2550
|
});
|
|
2550
2551
|
|
|
2551
2552
|
// src/ai-plugin/common/ai-model.ts
|
|
2552
|
-
var MODELS;
|
|
2553
|
+
var PROVIDERS, MODELS;
|
|
2553
2554
|
var init_ai_model = __esm({
|
|
2554
2555
|
"src/ai-plugin/common/ai-model.ts"() {
|
|
2555
2556
|
"use strict";
|
|
2557
|
+
PROVIDERS = ["openai", "anthropic", "google-genai", "ollama"];
|
|
2556
2558
|
MODELS = [
|
|
2557
|
-
|
|
2558
|
-
{ id: "
|
|
2559
|
-
{ id: "
|
|
2560
|
-
{ id: "
|
|
2561
|
-
|
|
2562
|
-
{ id: "
|
|
2563
|
-
{ id: "
|
|
2564
|
-
{ id: "
|
|
2565
|
-
|
|
2566
|
-
{ id: "
|
|
2559
|
+
// OpenAI models
|
|
2560
|
+
{ id: "gpt-5.5", name: "GPT-5.5", tool: true, provider: "openai" },
|
|
2561
|
+
{ id: "gpt-5.4", name: "GPT-5.4", tool: true, provider: "openai" },
|
|
2562
|
+
{ id: "gpt-5.4-mini", name: "GPT-5.4 mini", tool: true, provider: "openai" },
|
|
2563
|
+
// Anthropic Claude models
|
|
2564
|
+
{ id: "claude-opus-4-7", name: "Claude Opus 4.7", tool: true, provider: "anthropic" },
|
|
2565
|
+
{ id: "claude-sonnet-4-6", name: "Claude Sonnet 4.6", tool: true, provider: "anthropic" },
|
|
2566
|
+
{ id: "claude-haiku-4-5", name: "Claude Haiku 4.5", tool: true, provider: "anthropic" },
|
|
2567
|
+
// Google Gemini models
|
|
2568
|
+
{ id: "gemini-2.5-flash", name: "Gemini 2.5 Flash", tool: true, provider: "google-genai" },
|
|
2569
|
+
{ id: "gemini-2.5-flash-lite", name: "Gemini 2.5 Flash-Lite", tool: true, provider: "google-genai" },
|
|
2570
|
+
{ id: "gemini-2.5-pro", name: "Gemini 2.5 Pro", tool: true, provider: "google-genai" },
|
|
2571
|
+
// Ollama models
|
|
2572
|
+
{ id: "granite3.1-moe:latest", name: "Granite 3.1 Moe", tool: true, provider: "ollama" },
|
|
2573
|
+
{ id: "granite3.1-dense:latest", name: "Granite 3.1 Dense", tool: true, provider: "ollama" },
|
|
2574
|
+
{ id: "llama3:latest", name: "Llama 3", tool: false, provider: "ollama" },
|
|
2575
|
+
{ id: "llama3.2:latest", name: "Llama 3.2", tool: true, provider: "ollama" },
|
|
2576
|
+
{ id: "phi4:latest", name: "Phi 4", tool: false, provider: "ollama" },
|
|
2577
|
+
{ id: "phi3.5:latest", name: "Phi 3.5", tool: false, provider: "ollama" },
|
|
2578
|
+
{ id: "qwen3:4b", name: "Qwen 3 4B", tool: true, provider: "ollama" },
|
|
2579
|
+
{ id: "qwen3:latest", name: "Qwen 3", tool: true, provider: "ollama" }
|
|
2567
2580
|
];
|
|
2568
2581
|
}
|
|
2569
2582
|
});
|
|
@@ -2577,7 +2590,7 @@ var init_ai_preferences_service = __esm({
|
|
|
2577
2590
|
init_ai_service();
|
|
2578
2591
|
STORAGE_KEY_PREFERENCES = "ai.preferences";
|
|
2579
2592
|
DEFAULT_OPTIONS = {
|
|
2580
|
-
model: MODELS[0]
|
|
2593
|
+
model: MODELS[0]
|
|
2581
2594
|
};
|
|
2582
2595
|
AiPreferencesService = class {
|
|
2583
2596
|
loadOptions() {
|
|
@@ -2589,10 +2602,7 @@ var init_ai_preferences_service = __esm({
|
|
|
2589
2602
|
const updated = { ...this.loadOptions(), ...options };
|
|
2590
2603
|
localStorage.setItem(STORAGE_KEY_PREFERENCES, JSON.stringify(updated));
|
|
2591
2604
|
if (options.model) {
|
|
2592
|
-
|
|
2593
|
-
if (modelObj) {
|
|
2594
|
-
aiService.reset(modelObj);
|
|
2595
|
-
}
|
|
2605
|
+
aiService.reset(options.model);
|
|
2596
2606
|
}
|
|
2597
2607
|
}
|
|
2598
2608
|
};
|
|
@@ -2601,15 +2611,16 @@ var init_ai_preferences_service = __esm({
|
|
|
2601
2611
|
});
|
|
2602
2612
|
|
|
2603
2613
|
// src/ai-plugin/common/ai-service.ts
|
|
2604
|
-
var import_messages, import_google_genai, import_ollama, TOOLS, TOOLS_BY_NAME, AiService, aiService;
|
|
2614
|
+
var import_anthropic, import_messages, import_google_genai, import_ollama, import_openai, TOOLS, TOOLS_BY_NAME, AiService, aiService;
|
|
2605
2615
|
var init_ai_service = __esm({
|
|
2606
2616
|
"src/ai-plugin/common/ai-service.ts"() {
|
|
2607
2617
|
"use strict";
|
|
2618
|
+
import_anthropic = require("@langchain/anthropic");
|
|
2608
2619
|
import_messages = require("@langchain/core/messages");
|
|
2609
2620
|
import_google_genai = require("@langchain/google-genai");
|
|
2610
2621
|
import_ollama = require("@langchain/ollama");
|
|
2622
|
+
import_openai = require("@langchain/openai");
|
|
2611
2623
|
init_globals();
|
|
2612
|
-
init_ai_model();
|
|
2613
2624
|
init_ai_preferences_service();
|
|
2614
2625
|
TOOLS = [];
|
|
2615
2626
|
TOOLS_BY_NAME = TOOLS.reduce(
|
|
@@ -2632,7 +2643,23 @@ var init_ai_service = __esm({
|
|
|
2632
2643
|
const { token } = aiPreferencesService.loadOptions();
|
|
2633
2644
|
this.model = model;
|
|
2634
2645
|
try {
|
|
2635
|
-
switch (this.model.
|
|
2646
|
+
switch (this.model.provider) {
|
|
2647
|
+
case "openai":
|
|
2648
|
+
this.llm = new import_openai.ChatOpenAI({
|
|
2649
|
+
model: this.model.id,
|
|
2650
|
+
apiKey: token,
|
|
2651
|
+
temperature: 0,
|
|
2652
|
+
streaming: false
|
|
2653
|
+
});
|
|
2654
|
+
break;
|
|
2655
|
+
case "anthropic":
|
|
2656
|
+
this.llm = new import_anthropic.ChatAnthropic({
|
|
2657
|
+
model: this.model.id,
|
|
2658
|
+
apiKey: token,
|
|
2659
|
+
temperature: 0,
|
|
2660
|
+
streaming: false
|
|
2661
|
+
});
|
|
2662
|
+
break;
|
|
2636
2663
|
case "google-genai":
|
|
2637
2664
|
this.llm = new import_google_genai.ChatGoogleGenerativeAI({
|
|
2638
2665
|
model: this.model.id,
|
|
@@ -2650,7 +2677,9 @@ var init_ai_service = __esm({
|
|
|
2650
2677
|
}
|
|
2651
2678
|
} catch (error) {
|
|
2652
2679
|
log.warn("Error initialising AI model:", error);
|
|
2680
|
+
this.llm = void 0;
|
|
2653
2681
|
}
|
|
2682
|
+
this.llmWithTools = void 0;
|
|
2654
2683
|
if (TOOLS.length !== 0 && this.model.tool) {
|
|
2655
2684
|
this.llmWithTools = this.llm?.bindTools(TOOLS);
|
|
2656
2685
|
}
|
|
@@ -2658,13 +2687,9 @@ var init_ai_service = __esm({
|
|
|
2658
2687
|
getLlm() {
|
|
2659
2688
|
if (!this.model || !this.llm) {
|
|
2660
2689
|
const { model } = aiPreferencesService.loadOptions();
|
|
2661
|
-
|
|
2662
|
-
this.reset(modelObj);
|
|
2663
|
-
}
|
|
2664
|
-
if (this.llmWithTools) {
|
|
2665
|
-
return this.llmWithTools;
|
|
2690
|
+
this.reset(model);
|
|
2666
2691
|
}
|
|
2667
|
-
return this.llm;
|
|
2692
|
+
return this.llmWithTools ?? this.llm;
|
|
2668
2693
|
}
|
|
2669
2694
|
async invoke(messages) {
|
|
2670
2695
|
const llm = this.getLlm();
|
|
@@ -15900,12 +15925,15 @@ var init_Attributes = __esm({
|
|
|
15900
15925
|
setAttributes(attrs);
|
|
15901
15926
|
setIsReading(false);
|
|
15902
15927
|
});
|
|
15903
|
-
attributeService.register(
|
|
15904
|
-
|
|
15905
|
-
|
|
15906
|
-
|
|
15928
|
+
attributeService.register(
|
|
15929
|
+
{ type: "read", mbean: objectName },
|
|
15930
|
+
(response) => {
|
|
15931
|
+
if (response && !Jolokia.isError(response)) {
|
|
15932
|
+
log.debug("Scheduler - Attributes:", response.value);
|
|
15933
|
+
setAttributes(response.value);
|
|
15934
|
+
}
|
|
15907
15935
|
}
|
|
15908
|
-
|
|
15936
|
+
);
|
|
15909
15937
|
return () => attributeService.unregisterAll();
|
|
15910
15938
|
}, [selectedNode]);
|
|
15911
15939
|
(0, import_react10.useEffect)(() => {
|
|
@@ -15940,6 +15968,16 @@ var init_Attributes = __esm({
|
|
|
15940
15968
|
setIsModalOpen(true);
|
|
15941
15969
|
}
|
|
15942
15970
|
};
|
|
15971
|
+
const showDiagnosisResult = () => {
|
|
15972
|
+
if (!isModalOpen && Object.keys(attributes).length > 0) {
|
|
15973
|
+
if (!isAttributeSelected) {
|
|
15974
|
+
const name2 = Object.keys(attributes).sort((a, b) => a > b ? 1 : -1)[0];
|
|
15975
|
+
setSelected({ name: name2, value: String(attributes[name2]) });
|
|
15976
|
+
setIsAttributeSelected(true);
|
|
15977
|
+
}
|
|
15978
|
+
setIsModalOpen(true);
|
|
15979
|
+
}
|
|
15980
|
+
};
|
|
15943
15981
|
const getSortParams = () => ({
|
|
15944
15982
|
sortBy: {
|
|
15945
15983
|
index: 0,
|
|
@@ -15966,14 +16004,7 @@ var init_Attributes = __esm({
|
|
|
15966
16004
|
}
|
|
15967
16005
|
);
|
|
15968
16006
|
const attributesTable = /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { id: "attribute-table-with-panel", children: [
|
|
15969
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
15970
|
-
AiJmxToolbar,
|
|
15971
|
-
{
|
|
15972
|
-
attributes,
|
|
15973
|
-
setAiMessage,
|
|
15974
|
-
onDiagnosisFinished: () => setIsModalOpen(true)
|
|
15975
|
-
}
|
|
15976
|
-
),
|
|
16007
|
+
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(AiJmxToolbar, { attributes, setAiMessage, onDiagnosisFinished: showDiagnosisResult }),
|
|
15977
16008
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_table.Table, { "aria-label": "Attributes", variant: "compact", children: [
|
|
15978
16009
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Thead, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_react_table.Tr, { children: [
|
|
15979
16010
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_react_table.Th, { sort: getSortParams(), children: "Attribute" }),
|
|
@@ -16078,14 +16109,17 @@ var init_AttributeTable2 = __esm({
|
|
|
16078
16109
|
const setJobForSpecificNode = async (node2) => {
|
|
16079
16110
|
if (!node2 || !node2?.objectName) return;
|
|
16080
16111
|
const mbean = node2.objectName;
|
|
16081
|
-
attributeService.register(
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16112
|
+
attributeService.register(
|
|
16113
|
+
{ type: "read", mbean },
|
|
16114
|
+
(response) => {
|
|
16115
|
+
if (response && typeof response === "object" && "value" in response) {
|
|
16116
|
+
setAttributesList((attributesList2) => {
|
|
16117
|
+
attributesList2[mbean] = response.value;
|
|
16118
|
+
return { ...attributesList2 };
|
|
16119
|
+
});
|
|
16120
|
+
}
|
|
16087
16121
|
}
|
|
16088
|
-
|
|
16122
|
+
);
|
|
16089
16123
|
};
|
|
16090
16124
|
const setReadingJobs = async (currentSelection) => {
|
|
16091
16125
|
if (!currentSelection) return;
|
|
@@ -16363,23 +16397,46 @@ init_ai_preferences_service();
|
|
|
16363
16397
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
16364
16398
|
var AiPreferences = () => {
|
|
16365
16399
|
const [options, setOptions] = (0, import_react18.useState)(aiPreferencesService.loadOptions());
|
|
16400
|
+
const [provider, setProvider] = (0, import_react18.useState)(options.model.provider);
|
|
16401
|
+
const [models, setModels] = (0, import_react18.useState)(MODELS.filter((m) => m.provider === provider));
|
|
16366
16402
|
const [passwordHidden, setPasswordHidden] = (0, import_react18.useState)(true);
|
|
16367
|
-
const
|
|
16368
|
-
|
|
16369
|
-
|
|
16403
|
+
const updateProvider = (provider2) => {
|
|
16404
|
+
setProvider(provider2);
|
|
16405
|
+
setModels(MODELS.filter((m) => m.provider === provider2));
|
|
16406
|
+
};
|
|
16407
|
+
const updateModel = (updated) => {
|
|
16408
|
+
const model = MODELS.find((m) => m.id === updated);
|
|
16409
|
+
if (model) {
|
|
16410
|
+
aiPreferencesService.saveOptions({ model });
|
|
16411
|
+
setOptions({ ...options, model });
|
|
16412
|
+
}
|
|
16413
|
+
};
|
|
16414
|
+
const updateToken = (updated) => {
|
|
16415
|
+
aiPreferencesService.saveOptions({ token: updated });
|
|
16416
|
+
setOptions({ ...options, token: updated });
|
|
16370
16417
|
};
|
|
16371
16418
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.CardBody, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.Form, { isHorizontal: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_core7.FormSection, { title: "AI", titleElement: "h2", children: [
|
|
16372
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormGroup, { fieldId: "ai-prefs-form-
|
|
16419
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormGroup, { fieldId: "ai-prefs-form-provider", label: "Provider", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
16420
|
+
import_react_core7.FormSelect,
|
|
16421
|
+
{
|
|
16422
|
+
id: "ai-prefs-form-provider-input",
|
|
16423
|
+
"aria-label": "Form Select Provider",
|
|
16424
|
+
value: provider,
|
|
16425
|
+
onChange: (_, provider2) => updateProvider(provider2),
|
|
16426
|
+
children: PROVIDERS.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormSelectOption, { value: p, label: p }, i))
|
|
16427
|
+
}
|
|
16428
|
+
) }),
|
|
16429
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormGroup, { fieldId: "ai-prefs-form-model", label: "Model", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
16373
16430
|
import_react_core7.FormSelect,
|
|
16374
16431
|
{
|
|
16375
16432
|
id: "ai-prefs-form-model-input",
|
|
16376
16433
|
"aria-label": "Form Select Model",
|
|
16377
|
-
value: options.model,
|
|
16378
|
-
onChange: (_,
|
|
16379
|
-
children:
|
|
16434
|
+
value: options.model.id,
|
|
16435
|
+
onChange: (_, id) => updateModel(id),
|
|
16436
|
+
children: models.map((m) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormSelectOption, { value: m.id, label: m.name }, m.id))
|
|
16380
16437
|
}
|
|
16381
16438
|
) }),
|
|
16382
|
-
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormGroup, { fieldId: "ai-prefs-form-token", label: "
|
|
16439
|
+
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.FormGroup, { fieldId: "ai-prefs-form-token", label: "API Key / Token (optional)", children: /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(import_react_core7.InputGroup, { children: [
|
|
16383
16440
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.InputGroupItem, { isFill: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
16384
16441
|
import_react_core7.TextInput,
|
|
16385
16442
|
{
|
|
@@ -16387,7 +16444,7 @@ var AiPreferences = () => {
|
|
|
16387
16444
|
"aria-label": "Form Select Token",
|
|
16388
16445
|
type: passwordHidden ? "password" : "text",
|
|
16389
16446
|
value: options.token,
|
|
16390
|
-
onChange: (_, token) =>
|
|
16447
|
+
onChange: (_, token) => updateToken(token)
|
|
16391
16448
|
}
|
|
16392
16449
|
) }),
|
|
16393
16450
|
/* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_react_core7.InputGroupItem, { children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
|
|
@@ -16420,7 +16477,7 @@ var plugin = () => {
|
|
|
16420
16477
|
aiCommon();
|
|
16421
16478
|
jmxAi();
|
|
16422
16479
|
};
|
|
16423
|
-
import_react21.configManager.addProductInfo("Hawtio AI Plugin", "0.1.
|
|
16480
|
+
import_react21.configManager.addProductInfo("Hawtio AI Plugin", "0.1.6");
|
|
16424
16481
|
// Annotate the CommonJS export names for ESM import in node:
|
|
16425
16482
|
0 && (module.exports = {
|
|
16426
16483
|
plugin
|