@kwirthmagnify/kwirth-plugin-pinocchio 0.2.12 → 0.2.14

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.
Files changed (3) hide show
  1. package/back.js +62 -64
  2. package/front.js +20 -5
  3. package/package.json +1 -1
package/back.js CHANGED
@@ -11884,76 +11884,74 @@ Please provide a comprehensive answer based on the above data.`;
11884
11884
  break;
11885
11885
  case "events":
11886
11886
  let eventsEvent = event;
11887
- if (eventsEvent.type === "ADDED") {
11888
- try {
11889
- for (let t of this.pinocchioConfig.triggers.filter((t2) => t2.trigger === "artifact" && t2.kind === eventsEvent.obj.kind)) {
11890
- for (let version of t.versions.filter((v) => v.enabled)) {
11891
- this.backChannelObject.logInfo?.(`[pinocchio] added ${eventsEvent.obj.kind} ${eventsEvent.obj.metadata?.name}`);
11892
- if (eventsEvent.obj?.metadata?.creationTimestamp) {
11893
- let creationTs = Date.parse(eventsEvent.obj?.metadata?.creationTimestamp);
11894
- if (creationTs < this.startTime) {
11895
- this.backChannelObject.logWarning?.(`[pinocchio] bypass object analysis, creation timestamp is previous for object ${eventsEvent.obj?.metadata?.name} and kind ${t.kind} for LLM ${version.llm}`);
11896
- continue;
11897
- }
11887
+ try {
11888
+ for (let t of this.pinocchioConfig.triggers.filter((t2) => t2.trigger === "artifact" && t2.kind === eventsEvent.obj.kind && (!t2.k8sEvent || t2.k8sEvent === eventsEvent.type))) {
11889
+ for (let version of t.versions.filter((v) => v.enabled)) {
11890
+ this.backChannelObject.logInfo?.(`[pinocchio] ${eventsEvent.type} ${eventsEvent.obj.kind} ${eventsEvent.obj.metadata?.name}`);
11891
+ if (eventsEvent.type === "ADDED" && eventsEvent.obj?.metadata?.creationTimestamp) {
11892
+ let creationTs = Date.parse(eventsEvent.obj?.metadata?.creationTimestamp);
11893
+ if (creationTs < this.startTime) {
11894
+ this.backChannelObject.logWarning?.(`[pinocchio] bypass object analysis, creation timestamp is previous for object ${eventsEvent.obj?.metadata?.name} and kind ${t.kind} for LLM ${version.llm}`);
11895
+ continue;
11898
11896
  }
11899
- let { llmModelId, llmProviderId, model, temperature, providerOptions, errorPath, system, prompt, tools, toolContext } = await this.buildModelInvocation(t, version, eventsEvent) || {};
11900
- if (!model) return;
11897
+ }
11898
+ let { llmModelId, llmProviderId, model, temperature, providerOptions, errorPath, system, prompt, tools, toolContext } = await this.buildModelInvocation(t, version, eventsEvent) || {};
11899
+ if (!model) return;
11900
+ try {
11901
+ const { output, usage } = await (0, import_back.runWithToolContext)(toolContext, () => (0, import_back2.generateText)({
11902
+ model,
11903
+ temperature,
11904
+ tools,
11905
+ providerOptions,
11906
+ output: import_back2.Output.object({
11907
+ schema: import_back2.z.object({
11908
+ findings: import_back2.z.array(
11909
+ import_back2.z.object({
11910
+ description: import_back2.z.string().min(1),
11911
+ level: import_back2.z.enum(["low", "medium", "high", "critical"])
11912
+ })
11913
+ ),
11914
+ report: import_back2.z.string().min(1),
11915
+ hardened_yaml: import_back2.z.string().min(1)
11916
+ })
11917
+ }),
11918
+ system: system || "You are a very polite AI system",
11919
+ prompt: prompt || "Hi AI, how are you?"
11920
+ }));
11921
+ let analysis = {
11922
+ text: `${eventsEvent.type} ${eventsEvent.obj.kind} '${eventsEvent.obj.metadata.name}' in namespace '${eventsEvent.obj.metadata.namespace}' [LLM:${llmProviderId}/${llmModelId}, IN:${usage.inputTokens}, OUT:${usage.outputTokens}]`,
11923
+ findings: output.findings,
11924
+ ...output.report ? { report: output.report } : {},
11925
+ ...output.hardened_yaml ? { hardened_yaml: output.hardened_yaml } : {},
11926
+ timestamp: Date.now(),
11927
+ usage: {
11928
+ input: usage.inputTokens,
11929
+ output: usage.outputTokens
11930
+ },
11931
+ pod: eventsEvent.obj
11932
+ };
11933
+ this.analysis.push(analysis);
11934
+ this.broadcastAnalysis(analysis);
11935
+ } catch (err) {
11936
+ let message = `Pinocchio analysis ended in error while processing 'events' when analyzing '${eventsEvent.obj.metadata.name}' in namespace '${eventsEvent.obj.metadata.namespace}' [Kind:${eventsEvent.obj.kind}]`;
11937
+ this.backChannelObject.logError?.(`${message}: ${err}`);
11901
11938
  try {
11902
- const { output, usage } = await (0, import_back.runWithToolContext)(toolContext, () => (0, import_back2.generateText)({
11903
- model,
11904
- temperature,
11905
- tools,
11906
- providerOptions,
11907
- output: import_back2.Output.object({
11908
- schema: import_back2.z.object({
11909
- findings: import_back2.z.array(
11910
- import_back2.z.object({
11911
- description: import_back2.z.string().min(1),
11912
- level: import_back2.z.enum(["low", "medium", "high", "critical"])
11913
- })
11914
- ),
11915
- report: import_back2.z.string().min(1),
11916
- hardened_yaml: import_back2.z.string().min(1)
11917
- })
11918
- }),
11919
- system: system || "You are a very polite AI system",
11920
- prompt: prompt || "Hi AI, how are you?"
11921
- }));
11922
- let analysis = {
11923
- text: `${eventsEvent.type} ${eventsEvent.obj.kind} '${eventsEvent.obj.metadata.name}' in namespace '${eventsEvent.obj.metadata.namespace}' [LLM:${llmProviderId}/${llmModelId}, IN:${usage.inputTokens}, OUT:${usage.outputTokens}]`,
11924
- findings: output.findings,
11925
- ...output.report ? { report: output.report } : {},
11926
- ...output.hardened_yaml ? { hardened_yaml: output.hardened_yaml } : {},
11927
- timestamp: Date.now(),
11928
- usage: {
11929
- input: usage.inputTokens,
11930
- output: usage.outputTokens
11931
- },
11932
- pod: eventsEvent.obj
11933
- };
11934
- this.analysis.push(analysis);
11935
- this.broadcastAnalysis(analysis);
11936
- } catch (err) {
11937
- let message = `Pinocchio analysis ended in error while processing 'events' when analyzing '${eventsEvent.obj.metadata.name}' in namespace '${eventsEvent.obj.metadata.namespace}' [Kind:${eventsEvent.obj.kind}]`;
11938
- this.backChannelObject.logError?.(`${message}: ${err}`);
11939
- try {
11940
- let msg = _.get(err, errorPath);
11941
- } catch {
11942
- }
11943
- let an = {
11944
- findings: [
11945
- { description: message, level: "critical" },
11946
- { description: JSON.stringify(err), level: "critical" }
11947
- ],
11948
- timestamp: Date.now()
11949
- };
11950
- this.broadcastAnalysis(an);
11939
+ let msg = _.get(err, errorPath);
11940
+ } catch {
11951
11941
  }
11942
+ let an = {
11943
+ findings: [
11944
+ { description: message, level: "critical" },
11945
+ { description: JSON.stringify(err), level: "critical" }
11946
+ ],
11947
+ timestamp: Date.now()
11948
+ };
11949
+ this.broadcastAnalysis(an);
11952
11950
  }
11953
11951
  }
11954
- } catch (err) {
11955
- this.backChannelObject.logError?.(`[pinocchio] error in processProviderEvent: ${err}`);
11956
11952
  }
11953
+ } catch (err) {
11954
+ this.backChannelObject.logError?.(`[pinocchio] error in processProviderEvent: ${err}`);
11957
11955
  }
11958
11956
  break;
11959
11957
  default:
package/front.js CHANGED
@@ -88,6 +88,7 @@
88
88
 
89
89
  // src/common/PinocchioConfig.ts
90
90
  var kindsAvailable = ["Pod", "Deployment", "DaemonSet", "StatefulSet", "ReplicaSet", "Job", "CronJob", "ReplicationController", "Service", "Ingress", "HTTPRoute"];
91
+ var k8sEventsAvailable = ["ADDED", "MODIFIED", "DELETED"];
91
92
  var PinocchioConfig = class {
92
93
  constructor() {
93
94
  this.triggers = [];
@@ -174,6 +175,7 @@
174
175
  const [triggerId, setTriggerId] = (0, import_react3.useState)("");
175
176
  const [triggerType, setTriggerType] = (0, import_react3.useState)("artifact");
176
177
  const [triggerKind, setTriggerKind] = (0, import_react3.useState)("");
178
+ const [triggerK8sEvent, setTriggerK8sEvent] = (0, import_react3.useState)("");
177
179
  const [selectedVersionIndex, setSelectedVersionIndex] = (0, import_react3.useState)(null);
178
180
  const [msgBox, setMsgBox] = (0, import_react3.useState)(/* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null));
179
181
  const [versionId, setVersionId] = (0, import_react3.useState)("");
@@ -209,6 +211,7 @@
209
211
  setTriggerId(config.triggers[index].id);
210
212
  setTriggerType(config.triggers[index].trigger);
211
213
  setTriggerKind(config.triggers[index].kind ?? "");
214
+ setTriggerK8sEvent(config.triggers[index].k8sEvent ?? "");
212
215
  setSelectedVersionIndex(null);
213
216
  clearVersionEditor();
214
217
  };
@@ -233,6 +236,13 @@
233
236
  newTriggers[selectedTriggerIndex] = { ...newTriggers[selectedTriggerIndex], kind: newKind };
234
237
  setConfig((c) => ({ ...c, triggers: newTriggers }));
235
238
  };
239
+ const onTriggerK8sEventChange = (newEvent) => {
240
+ if (selectedTriggerIndex === null) return;
241
+ setTriggerK8sEvent(newEvent);
242
+ const newTriggers = [...config.triggers ?? []];
243
+ newTriggers[selectedTriggerIndex] = { ...newTriggers[selectedTriggerIndex], k8sEvent: newEvent || void 0 };
244
+ setConfig((c) => ({ ...c, triggers: newTriggers }));
245
+ };
236
246
  const onTriggerAdd = () => {
237
247
  const id = newTriggerId.trim() || `trigger-${(config.triggers ?? []).length + 1}`;
238
248
  const t = { id, trigger: "artifact", versions: [] };
@@ -347,7 +357,7 @@
347
357
  if (e.key === "Enter") onTriggerAdd();
348
358
  }
349
359
  }
350
- ), /* @__PURE__ */ import_react3.default.createElement(import_material2.IconButton, { size: "small", onClick: onTriggerAdd }, /* @__PURE__ */ import_react3.default.createElement(import_icons_material3.Add, { fontSize: "small" })), /* @__PURE__ */ import_react3.default.createElement(import_material2.IconButton, { size: "small", onClick: onTriggerDelete, disabled: selectedTriggerIndex === null, color: "error" }, /* @__PURE__ */ import_react3.default.createElement(import_icons_material3.Delete, { fontSize: "small" }))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: "0 0 auto", maxHeight: "40%", overflowY: "auto", overflowX: "hidden" } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.List, { dense: true, sx: { py: 0 } }, (config.triggers ?? []).map((t, index) => /* @__PURE__ */ import_react3.default.createElement(import_material2.ListItemButton, { key: index, selected: selectedTriggerIndex === index, onClick: () => onTriggerSelect(index), dense: true }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "column" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "body2", sx: { fontWeight: selectedTriggerIndex === index ? "bold" : "normal" } }, t.id), /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { color: "textSecondary", fontSize: 10 }, t.trigger, t.kind ? ` \xB7 ${t.kind}` : "")))))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Divider, { sx: { my: 0.5 } }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary", sx: { fontWeight: "bold", px: 0.5 } }, "Versions", selectedTrigger ? ` \u2014 ${selectedTrigger.id}` : ""), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, overflowY: "auto", overflowX: "hidden" } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.List, { dense: true, sx: { py: 0 } }, (selectedTrigger?.versions ?? []).map((v, index) => /* @__PURE__ */ import_react3.default.createElement(import_material2.ListItemButton, { key: index, selected: selectedVersionIndex === index, onClick: () => onVersionSelect(v, index), dense: true, sx: { py: 0.5 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Switch, { size: "small", checked: v.enabled, onChange: () => onVersionToggle(index), onClick: (e) => e.stopPropagation(), sx: { mr: 0.5 } }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "column" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "body2", sx: { fontWeight: selectedVersionIndex === index ? "bold" : "normal" } }, v.id), v.description && /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary", sx: { lineHeight: 1.2 } }, v.description))))))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", padding: "8px 8px 8px 16px", minHeight: 0 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { spacing: 1, sx: { width: "100%", height: "100%", display: "flex", flexDirection: "column" } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "row", spacing: 1 }, /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: triggerId, onChange: (e) => onTriggerIdChange(e.target.value), placeholder: "Trigger id", label: "Trigger ID", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "Trigger type"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: triggerType, onChange: (e) => onTriggerTypeChange(e.target.value), variant: "standard" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { value: "artifact" }, "artifact"), /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { value: "business" }, "business"))), triggerType === "artifact" && /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "Kind"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: triggerKind, onChange: (e) => onTriggerKindChange(e.target.value), variant: "standard" }, kindsAvailable.map((k) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: k, value: k }, k)))), triggerType === "business" && /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: spaces, onChange: (e) => setSpaces(e.target.value), placeholder: "space.type,...", label: "Spaces", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: versionId, onChange: (e) => setVersionId(e.target.value), placeholder: "Version id", label: "Version ID", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null })), /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Short description", label: "Description", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "row", alignItems: "flex-end", spacing: 1 }, /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", sx: { minWidth: 100 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "Action"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: action, onChange: (e) => setAction(e.target.value), variant: "standard", disabled: selectedTriggerIndex === null }, ["inform", "cancel", "repair"].map((v) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: v, value: v }, v)))), /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", sx: { minWidth: 120 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "LLM"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: llm, onChange: (e) => setLlm(e.target.value), variant: "standard", disabled: selectedTriggerIndex === null }, config.llms.map((l) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: l.id, value: l.id }, l.id)))), /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: steps, onChange: (e) => setSteps(+e.target.value), variant: "standard", type: "number", sx: { width: 60 }, label: "Steps", disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ import_react3.default.createElement(
360
+ ), /* @__PURE__ */ import_react3.default.createElement(import_material2.IconButton, { size: "small", onClick: onTriggerAdd }, /* @__PURE__ */ import_react3.default.createElement(import_icons_material3.Add, { fontSize: "small" })), /* @__PURE__ */ import_react3.default.createElement(import_material2.IconButton, { size: "small", onClick: onTriggerDelete, disabled: selectedTriggerIndex === null, color: "error" }, /* @__PURE__ */ import_react3.default.createElement(import_icons_material3.Delete, { fontSize: "small" }))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: "0 0 auto", maxHeight: "40%", overflowY: "auto", overflowX: "hidden" } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.List, { dense: true, sx: { py: 0 } }, (config.triggers ?? []).map((t, index) => /* @__PURE__ */ import_react3.default.createElement(import_material2.ListItemButton, { key: index, selected: selectedTriggerIndex === index, onClick: () => onTriggerSelect(index), dense: true }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "column" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "body2", sx: { fontWeight: selectedTriggerIndex === index ? "bold" : "normal" } }, t.id), /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { color: "textSecondary", fontSize: 10 }, t.trigger, t.kind ? ` \xB7 ${t.kind}` : "")))))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Divider, { sx: { my: 0.5 } }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary", sx: { fontWeight: "bold", px: 0.5 } }, "Versions", selectedTrigger ? ` \u2014 ${selectedTrigger.id}` : ""), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, overflowY: "auto", overflowX: "hidden" } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.List, { dense: true, sx: { py: 0 } }, (selectedTrigger?.versions ?? []).map((v, index) => /* @__PURE__ */ import_react3.default.createElement(import_material2.ListItemButton, { key: index, selected: selectedVersionIndex === index, onClick: () => onVersionSelect(v, index), dense: true, sx: { py: 0.5 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Switch, { size: "small", checked: v.enabled, onChange: () => onVersionToggle(index), onClick: (e) => e.stopPropagation(), sx: { mr: 0.5 } }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "column" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "body2", sx: { fontWeight: selectedVersionIndex === index ? "bold" : "normal" } }, v.id), v.description && /* @__PURE__ */ import_react3.default.createElement(import_material2.Typography, { variant: "caption", color: "text.secondary", sx: { lineHeight: 1.2 } }, v.description))))))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, minWidth: 0, display: "flex", flexDirection: "column", padding: "8px 8px 8px 16px", minHeight: 0 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { spacing: 1, sx: { width: "100%", height: "100%", display: "flex", flexDirection: "column" } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "row", spacing: 1 }, /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, display: "flex", gap: 1 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: triggerId, onChange: (e) => onTriggerIdChange(e.target.value), placeholder: "Trigger id", label: "Trigger ID", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "Trigger type"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: triggerType, onChange: (e) => onTriggerTypeChange(e.target.value), variant: "standard" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { value: "artifact" }, "artifact"), /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { value: "business" }, "business")))), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, display: "flex", gap: 1 } }, triggerType === "artifact" && /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "Kind"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: triggerKind, onChange: (e) => onTriggerKindChange(e.target.value), variant: "standard" }, kindsAvailable.map((k) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: k, value: k }, k)))), triggerType === "artifact" && /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "K8s Event"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: triggerK8sEvent, onChange: (e) => onTriggerK8sEventChange(e.target.value), variant: "standard" }, /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { value: "" }, /* @__PURE__ */ import_react3.default.createElement("em", null, "Any")), k8sEventsAvailable.map((ev) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: ev, value: ev }, ev)))), triggerType === "business" && /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: spaces, onChange: (e) => setSpaces(e.target.value), placeholder: "space.type,...", label: "Spaces", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: versionId, onChange: (e) => setVersionId(e.target.value), placeholder: "Version id", label: "Version ID", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }))), /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: description, onChange: (e) => setDescription(e.target.value), placeholder: "Short description", label: "Description", variant: "standard", fullWidth: true, disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Stack, { direction: "row", alignItems: "flex-end", spacing: 1 }, /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", sx: { minWidth: 100 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "Action"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: action, onChange: (e) => setAction(e.target.value), variant: "standard", disabled: selectedTriggerIndex === null }, ["inform", "cancel", "repair"].map((v) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: v, value: v }, v)))), /* @__PURE__ */ import_react3.default.createElement(import_material2.FormControl, { variant: "standard", sx: { minWidth: 120 } }, /* @__PURE__ */ import_react3.default.createElement(import_material2.InputLabel, null, "LLM"), /* @__PURE__ */ import_react3.default.createElement(import_material2.Select, { value: llm, onChange: (e) => setLlm(e.target.value), variant: "standard", disabled: selectedTriggerIndex === null }, config.llms.map((l) => /* @__PURE__ */ import_react3.default.createElement(import_material2.MenuItem, { key: l.id, value: l.id }, l.id)))), /* @__PURE__ */ import_react3.default.createElement(import_material2.TextField, { value: steps, onChange: (e) => setSteps(+e.target.value), variant: "standard", type: "number", sx: { width: 60 }, label: "Steps", disabled: selectedTriggerIndex === null }), /* @__PURE__ */ import_react3.default.createElement(import_material2.Box, { sx: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ import_react3.default.createElement(
351
361
  ToolSelector,
352
362
  {
353
363
  tools: props.toolsAvailable,
@@ -475,6 +485,7 @@
475
485
  const [eventData, setEventData] = (0, import_react6.useState)(saved?.eventData ?? "");
476
486
  const [triggerType, setTriggerType] = (0, import_react6.useState)(saved?.triggerType ?? "business");
477
487
  const [artifactKind, setArtifactKind] = (0, import_react6.useState)(saved?.artifactKind ?? "");
488
+ const [artifactK8sEvent, setArtifactK8sEvent] = (0, import_react6.useState)(saved?.artifactK8sEvent ?? "");
478
489
  const [eventSpace, setEventSpace] = (0, import_react6.useState)(saved?.eventSpace ?? "launch");
479
490
  const [eventType, setEventType] = (0, import_react6.useState)(saved?.eventType ?? "immediate");
480
491
  const [systemHistory, setSystemHistory] = (0, import_react6.useState)(saved?.systemHistory ?? []);
@@ -518,7 +529,7 @@
518
529
  setArtifactHistory(newArtifactHistory);
519
530
  setBusinessHistory(newBusinessHistory);
520
531
  setSpaceTypeHistory(newSpaceTypeHistory);
521
- props.onStateChange({ llm, steps, tools, autoTools, promptType, system, prompt, eventData, triggerType, artifactKind, eventSpace, eventType, systemHistory: newSystemHistory, promptHistory: newPromptHistory, artifactHistory: newArtifactHistory, businessHistory: newBusinessHistory, spaceTypeHistory: newSpaceTypeHistory });
532
+ props.onStateChange({ llm, steps, tools, autoTools, promptType, system, prompt, eventData, triggerType, artifactKind, artifactK8sEvent: artifactK8sEvent || void 0, eventSpace, eventType, systemHistory: newSystemHistory, promptHistory: newPromptHistory, artifactHistory: newArtifactHistory, businessHistory: newBusinessHistory, spaceTypeHistory: newSpaceTypeHistory });
522
533
  props.onClose(newTrigger);
523
534
  };
524
535
  const openHistory = (e, type) => {
@@ -557,7 +568,10 @@
557
568
  const t = props.pinocchioConfig.triggers.find((tr) => tr.id === pendingImportTriggerId);
558
569
  if (t) {
559
570
  if (t.trigger === "artifact" || t.trigger === "business") setTriggerType(t.trigger);
560
- if (t.trigger === "artifact") setArtifactKind(t.kind ?? "");
571
+ if (t.trigger === "artifact") {
572
+ setArtifactKind(t.kind ?? "");
573
+ setArtifactK8sEvent(t.k8sEvent ?? "");
574
+ }
561
575
  const v = t.versions.find((v2) => v2.id === pendingImportVersionId) ?? t.versions[0];
562
576
  if (v) {
563
577
  setLlm(v.llm);
@@ -594,6 +608,7 @@
594
608
  if (cfg.promptType !== void 0) setPromptType(cfg.promptType);
595
609
  if (cfg.triggerType !== void 0) setTriggerType(cfg.triggerType);
596
610
  if (cfg.artifactKind !== void 0) setArtifactKind(cfg.artifactKind);
611
+ if (cfg.artifactK8sEvent !== void 0) setArtifactK8sEvent(cfg.artifactK8sEvent);
597
612
  if (cfg.eventSpace !== void 0) setEventSpace(cfg.eventSpace);
598
613
  if (cfg.eventType !== void 0) setEventType(cfg.eventType);
599
614
  if (cfg.eventData !== void 0) setEventData(cfg.eventData);
@@ -605,7 +620,7 @@
605
620
  if (uploadRef.current) uploadRef.current.value = "";
606
621
  };
607
622
  const downloadConfig = async () => {
608
- const config = { llm, steps, tools, autoTools, system, prompt, promptType, triggerType, artifactKind, eventSpace, eventType, eventData, action: "inform", spaces: [] };
623
+ const config = { llm, steps, tools, autoTools, system, prompt, promptType, triggerType, artifactKind, artifactK8sEvent: artifactK8sEvent || void 0, eventSpace, eventType, eventData, action: "inform", spaces: [] };
609
624
  const json = JSON.stringify(config, null, 2);
610
625
  const filename = `pinocchio-playground-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}.json`;
611
626
  const tauri = window.__TAURI__;
@@ -736,7 +751,7 @@
736
751
  markDirty();
737
752
  }, sx: { width: 80 } }), /* @__PURE__ */ import_react6.default.createElement(import_material5.Box, { sx: { flex: 1 } }), /* @__PURE__ */ import_react6.default.createElement(import_material5.ToggleButtonGroup, { value: triggerType, exclusive: true, size: "small", onChange: (_, v) => {
738
753
  if (v) setTriggerType(v);
739
- } }, /* @__PURE__ */ import_react6.default.createElement(import_material5.ToggleButton, { value: "business" }, "Business"), /* @__PURE__ */ import_react6.default.createElement(import_material5.ToggleButton, { value: "artifact" }, "Artifact")), /* @__PURE__ */ import_react6.default.createElement(import_material5.Box, { sx: { width: 310, flexShrink: 0, display: "flex", alignItems: "flex-end", gap: 1 } }, triggerType === "artifact" ? /* @__PURE__ */ import_react6.default.createElement(import_material5.FormControl, { variant: "standard", fullWidth: true }, /* @__PURE__ */ import_react6.default.createElement(import_material5.InputLabel, { shrink: true }, "Artifact Kind"), /* @__PURE__ */ import_react6.default.createElement(import_material5.Select, { value: artifactKind, onChange: (e) => setArtifactKind(e.target.value) }, kindsAvailable.map((k) => /* @__PURE__ */ import_react6.default.createElement(import_material5.MenuItem, { key: k, value: k }, k)))) : /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(import_material5.TextField, { label: "Space", variant: "standard", size: "small", value: eventSpace, onChange: (e) => setEventSpace(e.target.value), sx: { width: 120 } }), /* @__PURE__ */ import_react6.default.createElement(import_material5.TextField, { label: "Type", variant: "standard", size: "small", value: eventType, onChange: (e) => setEventType(e.target.value), sx: { width: 120 } }), /* @__PURE__ */ import_react6.default.createElement(import_material5.IconButton, { size: "small", onClick: (e) => openHistory(e, "spacetype"), disabled: spaceTypeHistory.length === 0 }, /* @__PURE__ */ import_react6.default.createElement(import_icons_material5.HistoryOutlined, { sx: { fontSize: 14 } }))))), /* @__PURE__ */ import_react6.default.createElement(import_material5.Box, { sx: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" } }, /* @__PURE__ */ import_react6.default.createElement(import_material5.Stack, { direction: "row", alignItems: "center", spacing: 0.5 }, /* @__PURE__ */ import_react6.default.createElement(import_material5.Typography, { variant: "caption", color: "text.secondary" }, triggerType === "artifact" ? "Artifact JSON" : "Event JSON"), /* @__PURE__ */ import_react6.default.createElement(import_material5.IconButton, { size: "small", onClick: (e) => openHistory(e, triggerType), disabled: (triggerType === "artifact" ? artifactHistory : businessHistory).length === 0 }, /* @__PURE__ */ import_react6.default.createElement(import_icons_material5.HistoryOutlined, { sx: { fontSize: 14 } }))), /* @__PURE__ */ import_react6.default.createElement(
754
+ } }, /* @__PURE__ */ import_react6.default.createElement(import_material5.ToggleButton, { value: "business" }, "Business"), /* @__PURE__ */ import_react6.default.createElement(import_material5.ToggleButton, { value: "artifact" }, "Artifact")), /* @__PURE__ */ import_react6.default.createElement(import_material5.Box, { sx: { flex: 1, minWidth: 0, display: "flex", alignItems: "flex-end", gap: 1 } }, triggerType === "artifact" ? /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(import_material5.FormControl, { variant: "standard", fullWidth: true }, /* @__PURE__ */ import_react6.default.createElement(import_material5.InputLabel, { shrink: true }, "Artifact Kind"), /* @__PURE__ */ import_react6.default.createElement(import_material5.Select, { value: artifactKind, onChange: (e) => setArtifactKind(e.target.value) }, kindsAvailable.map((k) => /* @__PURE__ */ import_react6.default.createElement(import_material5.MenuItem, { key: k, value: k }, k)))), /* @__PURE__ */ import_react6.default.createElement(import_material5.FormControl, { variant: "standard", fullWidth: true }, /* @__PURE__ */ import_react6.default.createElement(import_material5.InputLabel, { shrink: true }, "K8s Event"), /* @__PURE__ */ import_react6.default.createElement(import_material5.Select, { value: artifactK8sEvent, onChange: (e) => setArtifactK8sEvent(e.target.value) }, /* @__PURE__ */ import_react6.default.createElement(import_material5.MenuItem, { value: "" }, /* @__PURE__ */ import_react6.default.createElement("em", null, "Any")), k8sEventsAvailable.map((ev) => /* @__PURE__ */ import_react6.default.createElement(import_material5.MenuItem, { key: ev, value: ev }, ev))))) : /* @__PURE__ */ import_react6.default.createElement(import_react6.default.Fragment, null, /* @__PURE__ */ import_react6.default.createElement(import_material5.TextField, { label: "Space", variant: "standard", size: "small", value: eventSpace, onChange: (e) => setEventSpace(e.target.value), sx: { flex: 1 } }), /* @__PURE__ */ import_react6.default.createElement(import_material5.TextField, { label: "Type", variant: "standard", size: "small", value: eventType, onChange: (e) => setEventType(e.target.value), sx: { flex: 1 } }), /* @__PURE__ */ import_react6.default.createElement(import_material5.IconButton, { size: "small", onClick: (e) => openHistory(e, "spacetype"), disabled: spaceTypeHistory.length === 0 }, /* @__PURE__ */ import_react6.default.createElement(import_icons_material5.HistoryOutlined, { sx: { fontSize: 14 } }))))), /* @__PURE__ */ import_react6.default.createElement(import_material5.Box, { sx: { flex: 1, display: "flex", flexDirection: "column", overflow: "hidden" } }, /* @__PURE__ */ import_react6.default.createElement(import_material5.Stack, { direction: "row", alignItems: "center", spacing: 0.5 }, /* @__PURE__ */ import_react6.default.createElement(import_material5.Typography, { variant: "caption", color: "text.secondary" }, triggerType === "artifact" ? "Artifact JSON" : "Event JSON"), /* @__PURE__ */ import_react6.default.createElement(import_material5.IconButton, { size: "small", onClick: (e) => openHistory(e, triggerType), disabled: (triggerType === "artifact" ? artifactHistory : businessHistory).length === 0 }, /* @__PURE__ */ import_react6.default.createElement(import_icons_material5.HistoryOutlined, { sx: { fontSize: 14 } }))), /* @__PURE__ */ import_react6.default.createElement(
740
755
  "textarea",
741
756
  {
742
757
  value: eventData,
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "id": "pinocchio",
3
3
  "name": "@kwirthmagnify/kwirth-plugin-pinocchio",
4
4
  "displayName": "Pinocchio",
5
- "version": "0.2.12",
5
+ "version": "0.2.14",
6
6
  "description": "Pinocchio AI channel plugin for Kwirth - LLM-based Kubernetes event analysis",
7
7
  "icon": "AutoFixHigh",
8
8
  "website": "https://kwirthmagnify.dev"