@atomoz/workflows-nodes 0.1.20 → 0.1.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -917,13 +917,54 @@ var IaAgentNode = {
917
917
  name: "response",
918
918
  fieldType: "string"
919
919
  }
920
+ },
921
+ {
922
+ id: "beforeGuardrails",
923
+ label: "Before Guardrails",
924
+ type: "guardrail",
925
+ required: false,
926
+ typeable: false,
927
+ handle: {
928
+ type: "input",
929
+ label: "Before Guardrails",
930
+ name: "beforeGuardrails",
931
+ fieldType: "guardrail",
932
+ acceptTypes: ["guardrail"],
933
+ maxConnections: 10
934
+ }
935
+ },
936
+ {
937
+ id: "afterGuardrails",
938
+ label: "After Guardrails",
939
+ type: "guardrail",
940
+ required: false,
941
+ typeable: false,
942
+ handle: {
943
+ type: "input",
944
+ label: "After Guardrails",
945
+ name: "afterGuardrails",
946
+ fieldType: "guardrail",
947
+ acceptTypes: ["guardrail"],
948
+ maxConnections: 10
949
+ }
950
+ },
951
+ {
952
+ id: "guardrailMode",
953
+ label: "Guardrail Mode",
954
+ type: "select",
955
+ required: true,
956
+ defaultValue: "fail-first",
957
+ options: [
958
+ { label: "Fail on First Violation", value: "fail-first" },
959
+ { label: "Run All and Combine", value: "run-all" }
960
+ ]
920
961
  }
921
962
  ]
922
963
  };
923
964
 
924
965
  // src/nodes/ia/agent/function.ts
925
966
  import { createReactAgent } from "@langchain/langgraph/prebuilt";
926
- import { SystemMessage } from "@langchain/core/messages";
967
+ import { SystemMessage, HumanMessage } from "@langchain/core/messages";
927
968
 
928
969
  // src/utils/llm-factory.ts
929
970
  import { gql } from "graphql-request";
@@ -956,7 +997,7 @@ async function createLLMFromModel(modelConfig, authToken, streaming = false) {
956
997
  case "gemini":
957
998
  return new ChatGoogle({
958
999
  model: "gemini-flash-latest",
959
- apiKey: "AIzaSyAWS9GhesWxG4uTdJRQbBziMB1diXtXtlI",
1000
+ apiKey: "AIzaSyD9WiFuXp2fhVAokIMPp9YPKMlh7_Bvddc",
960
1001
  streaming
961
1002
  });
962
1003
  case "openai":
@@ -981,22 +1022,165 @@ async function createLLMFromModel(modelConfig, authToken, streaming = false) {
981
1022
  }
982
1023
  }
983
1024
 
1025
+ // src/utils/guardrail-executor.ts
1026
+ async function executeGuardrails(guardrails, content, mode = "fail-first") {
1027
+ const list = Array.isArray(guardrails) ? guardrails : [guardrails];
1028
+ const result = {
1029
+ passed: true,
1030
+ blocked: false,
1031
+ modifiedContent: content,
1032
+ violations: []
1033
+ };
1034
+ for (const guard of list) {
1035
+ if (!guard) continue;
1036
+ let guardPassed = true;
1037
+ let violationMessage = "";
1038
+ if (guard.type === "rule") {
1039
+ const { ruleType, config, action } = guard;
1040
+ if (ruleType === "keywords" && config) {
1041
+ const keywords = config.split(",").map((k) => k.trim().toLowerCase());
1042
+ const lowerContent = content.toLowerCase();
1043
+ const found = keywords.filter((k) => lowerContent.includes(k));
1044
+ if (found.length > 0) {
1045
+ guardPassed = false;
1046
+ violationMessage = `Conte\xFAdo cont\xE9m palavras proibidas: ${found.join(", ")}`;
1047
+ }
1048
+ } else if (ruleType === "regex" && config) {
1049
+ try {
1050
+ const regex = new RegExp(config, "i");
1051
+ if (regex.test(content)) {
1052
+ guardPassed = false;
1053
+ violationMessage = `Conte\xFAdo viola regra de padr\xE3o (regex): ${config}`;
1054
+ }
1055
+ } catch (e) {
1056
+ console.error("Invalid regex in guardrail:", config);
1057
+ }
1058
+ } else if (ruleType === "maxValue" && config) {
1059
+ const val = parseFloat(content.replace(/[^\d.-]/g, ""));
1060
+ const max = parseFloat(config);
1061
+ if (!isNaN(val) && val > max) {
1062
+ guardPassed = false;
1063
+ violationMessage = `Valor ${val} excede o m\xE1ximo permitido de ${max}.`;
1064
+ }
1065
+ } else if (ruleType === "minValue" && config) {
1066
+ const val = parseFloat(content.replace(/[^\d.-]/g, ""));
1067
+ const min = parseFloat(config);
1068
+ if (!isNaN(val) && val < min) {
1069
+ guardPassed = false;
1070
+ violationMessage = `Valor ${val} \xE9 menor que o m\xEDnimo permitido de ${min}.`;
1071
+ }
1072
+ }
1073
+ } else if (guard.type === "function") {
1074
+ const { nodeFunction, name } = guard;
1075
+ if (typeof nodeFunction === "function") {
1076
+ try {
1077
+ const result2 = await nodeFunction({
1078
+ input: content,
1079
+ fieldValues: { input: content },
1080
+ originalNodeData: guard.originalNodeData
1081
+ });
1082
+ if (result2 === false || typeof result2 === "object" && result2?.passed === false) {
1083
+ guardPassed = false;
1084
+ violationMessage = typeof result2?.message === "string" ? result2.message : `Fun\xE7\xE3o guardrail "${name}" reprovou o conte\xFAdo.`;
1085
+ } else if (typeof result2 === "object" && result2?.modifiedContent) {
1086
+ result2.modifiedContent = result2.modifiedContent;
1087
+ }
1088
+ } catch (error) {
1089
+ console.error(`Error executing function guardrail "${name}":`, error);
1090
+ guardPassed = false;
1091
+ violationMessage = `Erro na fun\xE7\xE3o guardrail: ${error instanceof Error ? error.message : String(error)}`;
1092
+ }
1093
+ }
1094
+ } else if (guard.type === "model") {
1095
+ const { model, evaluationPrompt, name } = guard;
1096
+ if (model && typeof model.invoke === "function") {
1097
+ try {
1098
+ const prompt = evaluationPrompt.replace("{{content}}", content);
1099
+ const response = await model.invoke(prompt);
1100
+ const resultText = typeof response.content === "string" ? response.content : String(response.content);
1101
+ if (resultText.toUpperCase().includes("UNSAFE")) {
1102
+ guardPassed = false;
1103
+ violationMessage = `Modelo de avalia\xE7\xE3o "${name}" detectou viola\xE7\xE3o de seguran\xE7a/pol\xEDtica.`;
1104
+ }
1105
+ } catch (error) {
1106
+ console.error(`Error executing model guardrail "${name}":`, error);
1107
+ }
1108
+ }
1109
+ }
1110
+ if (!guardPassed) {
1111
+ result.passed = false;
1112
+ result.violations.push({
1113
+ name: guard.name,
1114
+ message: violationMessage,
1115
+ action: guard.action || "block"
1116
+ });
1117
+ if (guard.action === "block") {
1118
+ result.blocked = true;
1119
+ result.message = violationMessage;
1120
+ if (mode === "fail-first") break;
1121
+ }
1122
+ }
1123
+ }
1124
+ return result;
1125
+ }
1126
+ function applyPromptGuardrails(systemMessage, guardrails) {
1127
+ const list = Array.isArray(guardrails) ? guardrails : [guardrails];
1128
+ let finalSystemMessage = systemMessage;
1129
+ for (const guard of list) {
1130
+ if (guard?.type === "prompt" && guard.prompt) {
1131
+ finalSystemMessage += `
1132
+
1133
+ GUARDRAIL [${guard.name}]: ${guard.prompt}`;
1134
+ }
1135
+ }
1136
+ return finalSystemMessage;
1137
+ }
1138
+
984
1139
  // src/nodes/ia/agent/function.ts
985
1140
  var IaAgentNodeFunction = async (inputs) => {
986
1141
  const { $field: _$field, $req: _$req, $inputs: _$inputs, $vars: _$vars } = inputs;
987
1142
  const fieldValues = inputs.fieldValues || {};
988
- const { model, tools, systemMessage, name, message } = fieldValues;
1143
+ const { model, tools, systemMessage, name, message, beforeGuardrails, afterGuardrails, guardrailMode } = fieldValues;
989
1144
  const authToken = inputs.authToken;
990
1145
  const stream = Boolean(inputs?.stream);
991
1146
  const emitter = inputs?.emitter;
992
1147
  const sessionMemory = fieldValues.sessionMemory || inputs.sessionMemory;
993
- const checkpointer = sessionMemory?.checkpointer;
1148
+ const checkpointer = sessionMemory && typeof sessionMemory.put === "function" ? sessionMemory : sessionMemory?.checkpointer;
994
1149
  const sessionId = inputs.sessionId || inputs.$req?.sessionId || `session-${Date.now()}`;
995
1150
  if (!name) {
996
1151
  throw new Error("Agent 'name' is required. Please provide a unique name for the agent in the node properties.");
997
1152
  }
998
- if (!model) {
999
- throw new Error("Model is required for IaAgentNode");
1153
+ const prepareGuardrails = async (list) => {
1154
+ const guardrailsList = Array.isArray(list) ? list : [list];
1155
+ return await Promise.all(guardrailsList.map(async (g) => {
1156
+ if (g?.type === "model" && g.model && !g.model.invoke) {
1157
+ if (!authToken) throw new Error("Auth token required for model guardrail");
1158
+ const modelInstance = await createLLMFromModel(g.model, authToken, false);
1159
+ return { ...g, model: modelInstance };
1160
+ }
1161
+ return g;
1162
+ }));
1163
+ };
1164
+ if (message && beforeGuardrails) {
1165
+ const preparedBefore = await prepareGuardrails(beforeGuardrails);
1166
+ const beforeResults = await executeGuardrails(preparedBefore, message, guardrailMode);
1167
+ if (beforeResults.blocked) {
1168
+ console.log(`\u{1F6E1}\uFE0F IaAgentNode "${name}": Blocked by before-agent guardrail:`, beforeResults.message);
1169
+ if (stream && emitter?.emitDelta) {
1170
+ emitter.emitDelta({
1171
+ content: beforeResults.message || "Requisi\xE7\xE3o bloqueada por pol\xEDtica de seguran\xE7a.",
1172
+ actor: name,
1173
+ isAgent: true,
1174
+ isError: true
1175
+ });
1176
+ }
1177
+ return {
1178
+ agent: null,
1179
+ output: beforeResults.message || "Requisi\xE7\xE3o bloqueada por pol\xEDtica de seguran\xE7a.",
1180
+ blocked: true,
1181
+ violations: beforeResults.violations
1182
+ };
1183
+ }
1000
1184
  }
1001
1185
  let toolsArray = [];
1002
1186
  if (Array.isArray(tools)) {
@@ -1004,9 +1188,15 @@ var IaAgentNodeFunction = async (inputs) => {
1004
1188
  } else if (tools) {
1005
1189
  toolsArray = [tools];
1006
1190
  }
1007
- const finalSystemMessageContent = `${systemMessage || ""}
1191
+ let finalSystemMessageContent = `${systemMessage || ""}
1008
1192
 
1009
1193
  IMPORTANT: You must base your response on the last message in the conversation history.`;
1194
+ if (beforeGuardrails) {
1195
+ finalSystemMessageContent = applyPromptGuardrails(finalSystemMessageContent, beforeGuardrails);
1196
+ }
1197
+ if (afterGuardrails) {
1198
+ finalSystemMessageContent = applyPromptGuardrails(finalSystemMessageContent, afterGuardrails);
1199
+ }
1010
1200
  const finalSystemMessage = new SystemMessage(finalSystemMessageContent);
1011
1201
  let llmInstance;
1012
1202
  if (model?.integrationId) {
@@ -1035,11 +1225,10 @@ IMPORTANT: You must base your response on the last message in the conversation h
1035
1225
  let output = "";
1036
1226
  if (message) {
1037
1227
  try {
1038
- const { HumanMessage: HumanMessage2 } = await import("@langchain/core/messages");
1039
1228
  const invokeConfig = checkpointer ? { configurable: { thread_id: sessionId } } : {};
1040
1229
  if (stream && emitter) {
1041
1230
  const streamIterator = await agent.stream(
1042
- { messages: [new HumanMessage2(message)] },
1231
+ { messages: [new HumanMessage(message)] },
1043
1232
  invokeConfig
1044
1233
  );
1045
1234
  let lastMessages = [];
@@ -1086,7 +1275,7 @@ IMPORTANT: You must base your response on the last message in the conversation h
1086
1275
  }
1087
1276
  } else {
1088
1277
  const result = await agent.invoke(
1089
- { messages: [new HumanMessage2(message)] },
1278
+ { messages: [new HumanMessage(message)] },
1090
1279
  invokeConfig
1091
1280
  );
1092
1281
  if (result?.messages && result.messages.length > 0) {
@@ -1105,6 +1294,26 @@ IMPORTANT: You must base your response on the last message in the conversation h
1105
1294
  }
1106
1295
  }
1107
1296
  }
1297
+ if (output && afterGuardrails) {
1298
+ const preparedAfter = await prepareGuardrails(afterGuardrails);
1299
+ const afterResults = await executeGuardrails(preparedAfter, output, guardrailMode);
1300
+ if (afterResults.blocked) {
1301
+ console.log(`\u{1F6E1}\uFE0F IaAgentNode "${name}": Response blocked by after-agent guardrail:`, afterResults.message);
1302
+ if (stream && emitter?.emitDelta) {
1303
+ emitter.emitDelta({
1304
+ content: `
1305
+
1306
+ \u26A0\uFE0F RESPOSTA BLOQUEADA: ${afterResults.message}`,
1307
+ actor: name,
1308
+ isAgent: true,
1309
+ isError: true
1310
+ });
1311
+ }
1312
+ output = afterResults.message || "Resposta bloqueada por pol\xEDtica de seguran\xE7a.";
1313
+ } else if (afterResults.modifiedContent) {
1314
+ output = afterResults.modifiedContent;
1315
+ }
1316
+ }
1108
1317
  } catch (error) {
1109
1318
  console.error("Error processing message in agent:", error);
1110
1319
  output = `Error: ${error instanceof Error ? error.message : "Unknown error"}`;
@@ -1219,7 +1428,7 @@ var AiSupervisorNode = {
1219
1428
 
1220
1429
  // src/nodes/ia/supervisor/function.ts
1221
1430
  import { createSupervisor } from "@langchain/langgraph-supervisor";
1222
- import { HumanMessage } from "@langchain/core/messages";
1431
+ import { HumanMessage as HumanMessage2 } from "@langchain/core/messages";
1223
1432
  import { InMemoryStore } from "@langchain/langgraph";
1224
1433
  var store = new InMemoryStore();
1225
1434
  var extractSupervisorAgents = (agents) => {
@@ -1312,7 +1521,7 @@ var AiSupervisorNodeFunction = async (params) => {
1312
1521
  if (stream && emitter) {
1313
1522
  try {
1314
1523
  const streamIterator = await app.stream(
1315
- { messages: [new HumanMessage({ content: message })] },
1524
+ { messages: [new HumanMessage2({ content: message })] },
1316
1525
  { recursionLimit: 150, configurable: { thread_id: sessionId } }
1317
1526
  );
1318
1527
  let finalMessages = [];
@@ -1391,7 +1600,7 @@ var AiSupervisorNodeFunction = async (params) => {
1391
1600
  }
1392
1601
  } else {
1393
1602
  const result = await app.invoke(
1394
- { messages: [new HumanMessage({ content: message })] },
1603
+ { messages: [new HumanMessage2({ content: message })] },
1395
1604
  { recursionLimit: 150, configurable: { thread_id: sessionId } }
1396
1605
  );
1397
1606
  const finalResponse = extractFinalResponse(result?.messages);
@@ -1508,7 +1717,7 @@ var PostgresMemoryNode = {
1508
1717
  label: "Connection String",
1509
1718
  type: "string",
1510
1719
  required: true,
1511
- defaultValue: "postgresql://postgres:postgres@localhost:5432/workflows",
1720
+ defaultValue: "postgresql://yugabyte:yugabyte@localhost:5433/workflows",
1512
1721
  placeholder: "postgresql://user:pass@host:5432/database"
1513
1722
  },
1514
1723
  {
@@ -2060,6 +2269,375 @@ var CustomCodeNode = {
2060
2269
  ]
2061
2270
  };
2062
2271
 
2272
+ // src/nodes/guardrails/prompt/data.ts
2273
+ import { z as z13 } from "zod";
2274
+ var PromptGuardrailNodeSchema = z13.object({
2275
+ name: z13.string().describe("Nome do guardrail"),
2276
+ prompt: z13.string().describe("Instru\xE7\xE3o do guardrail")
2277
+ });
2278
+ var PromptGuardrailNode = {
2279
+ label: "Prompt Guardrail",
2280
+ type: "PromptGuardrailNode",
2281
+ category: "step",
2282
+ description: "Injeta instru\xE7\xF5es de seguran\xE7a ou comportamento no sistema do agente",
2283
+ icon: "\u{1F6E1}\uFE0F",
2284
+ group: "Guardrails",
2285
+ tags: {
2286
+ execution: "sync",
2287
+ group: "Guardrails"
2288
+ },
2289
+ fields: [
2290
+ {
2291
+ id: "name",
2292
+ label: "Nome",
2293
+ type: "string",
2294
+ required: true,
2295
+ placeholder: "Ex: Enforce Portuguese"
2296
+ },
2297
+ {
2298
+ id: "prompt",
2299
+ label: "Instru\xE7\xE3o",
2300
+ type: "textarea",
2301
+ required: true,
2302
+ placeholder: "Ex: Sempre responda em portugu\xEAs brasileiro"
2303
+ },
2304
+ {
2305
+ id: "guardrail",
2306
+ label: "Guardrail",
2307
+ type: "guardrail",
2308
+ required: true,
2309
+ typeable: false,
2310
+ handle: {
2311
+ type: "output",
2312
+ label: "Guardrail",
2313
+ name: "guardrail",
2314
+ fieldType: "guardrail"
2315
+ }
2316
+ }
2317
+ ]
2318
+ };
2319
+
2320
+ // src/nodes/guardrails/prompt/function.ts
2321
+ var PromptGuardrailNodeFunction = async (inputs) => {
2322
+ const { fieldValues = {} } = inputs;
2323
+ const { name, prompt } = fieldValues;
2324
+ return {
2325
+ type: "prompt",
2326
+ name: name || "Prompt Guardrail",
2327
+ prompt: prompt || ""
2328
+ };
2329
+ };
2330
+
2331
+ // src/nodes/guardrails/rule/data.ts
2332
+ import { z as z14 } from "zod";
2333
+ var RuleGuardrailNodeSchema = z14.object({
2334
+ name: z14.string().describe("Nome do guardrail"),
2335
+ phase: z14.enum(["before", "after"]).describe("Fase de execu\xE7\xE3o"),
2336
+ ruleType: z14.enum(["maxValue", "minValue", "regex", "keywords", "pii"]).describe("Tipo de regra"),
2337
+ config: z14.any().describe("Configura\xE7\xE3o da regra"),
2338
+ action: z14.enum(["block", "warn", "modify"]).describe("A\xE7\xE3o em caso de viola\xE7\xE3o")
2339
+ });
2340
+ var RuleGuardrailNode = {
2341
+ label: "Rule Guardrail",
2342
+ type: "RuleGuardrailNode",
2343
+ category: "step",
2344
+ description: "Valida\xE7\xF5es determin\xEDsticas baseadas em regras (limites, palavras-chave, regex)",
2345
+ icon: "\u2696\uFE0F",
2346
+ group: "Guardrails",
2347
+ tags: {
2348
+ execution: "sync",
2349
+ group: "Guardrails"
2350
+ },
2351
+ fields: [
2352
+ {
2353
+ id: "name",
2354
+ label: "Nome",
2355
+ type: "string",
2356
+ required: true,
2357
+ placeholder: "Ex: Limit Discount"
2358
+ },
2359
+ {
2360
+ id: "phase",
2361
+ label: "Fase",
2362
+ type: "select",
2363
+ required: true,
2364
+ defaultValue: "after",
2365
+ options: [
2366
+ { label: "Antes do Agente (Input)", value: "before" },
2367
+ { label: "Depois do Agente (Output)", value: "after" }
2368
+ ]
2369
+ },
2370
+ {
2371
+ id: "ruleType",
2372
+ label: "Tipo de Regra",
2373
+ type: "select",
2374
+ required: true,
2375
+ options: [
2376
+ { label: "Valor M\xE1ximo", value: "maxValue" },
2377
+ { label: "Valor M\xEDnimo", value: "minValue" },
2378
+ { label: "Express\xE3o Regular (Regex)", value: "regex" },
2379
+ { label: "Palavras-chave (Keywords)", value: "keywords" },
2380
+ { label: "Dados Sens\xEDveis (PII)", value: "pii" }
2381
+ ]
2382
+ },
2383
+ {
2384
+ id: "config",
2385
+ label: "Configura\xE7\xE3o",
2386
+ type: "string",
2387
+ required: true,
2388
+ placeholder: "Ex: 15 (para valor) ou ofensivo,hack (para keywords)"
2389
+ },
2390
+ {
2391
+ id: "action",
2392
+ label: "A\xE7\xE3o em Viola\xE7\xE3o",
2393
+ type: "select",
2394
+ required: true,
2395
+ defaultValue: "block",
2396
+ options: [
2397
+ { label: "Bloquear Resposta", value: "block" },
2398
+ { label: "Avisar (Warning)", value: "warn" },
2399
+ { label: "Modificar/Ocultar", value: "modify" }
2400
+ ]
2401
+ },
2402
+ {
2403
+ id: "guardrail",
2404
+ label: "Guardrail",
2405
+ type: "guardrail",
2406
+ required: true,
2407
+ typeable: false,
2408
+ handle: {
2409
+ type: "output",
2410
+ label: "Guardrail",
2411
+ name: "guardrail",
2412
+ fieldType: "guardrail"
2413
+ }
2414
+ }
2415
+ ]
2416
+ };
2417
+
2418
+ // src/nodes/guardrails/rule/function.ts
2419
+ var RuleGuardrailNodeFunction = async (inputs) => {
2420
+ const { fieldValues = {} } = inputs;
2421
+ const { name, phase, ruleType, config, action } = fieldValues;
2422
+ return {
2423
+ type: "rule",
2424
+ name: name || "Rule Guardrail",
2425
+ phase: phase || "after",
2426
+ ruleType: ruleType || "keywords",
2427
+ config: config || "",
2428
+ action: action || "block"
2429
+ };
2430
+ };
2431
+
2432
+ // src/nodes/guardrails/function/data.ts
2433
+ import { z as z15 } from "zod";
2434
+ var FunctionGuardrailNodeSchema = z15.object({
2435
+ name: z15.string().describe("Nome do guardrail"),
2436
+ phase: z15.enum(["before", "after"]).describe("Fase de execu\xE7\xE3o"),
2437
+ description: z15.string().optional().describe("Descri\xE7\xE3o do que a fun\xE7\xE3o valida"),
2438
+ action: z15.enum(["block", "warn", "modify", "escalate"]).describe("A\xE7\xE3o em caso de viola\xE7\xE3o")
2439
+ });
2440
+ var FunctionGuardrailNode = {
2441
+ label: "Function Guardrail",
2442
+ type: "FunctionGuardrailNode",
2443
+ category: "step",
2444
+ description: "Executa uma fun\xE7\xE3o customizada (Custom Code ou HTTP) para validar entrada/sa\xEDda",
2445
+ icon: "\u{1F9E9}",
2446
+ group: "Guardrails",
2447
+ tags: {
2448
+ execution: "async",
2449
+ group: "Guardrails"
2450
+ },
2451
+ fields: [
2452
+ {
2453
+ id: "name",
2454
+ label: "Nome",
2455
+ type: "string",
2456
+ required: true,
2457
+ placeholder: "Ex: Validar Desconto API"
2458
+ },
2459
+ {
2460
+ id: "phase",
2461
+ label: "Fase",
2462
+ type: "select",
2463
+ required: true,
2464
+ defaultValue: "after",
2465
+ options: [
2466
+ { label: "Antes do Agente (Input)", value: "before" },
2467
+ { label: "Depois do Agente (Output)", value: "after" }
2468
+ ]
2469
+ },
2470
+ {
2471
+ id: "description",
2472
+ label: "Descri\xE7\xE3o",
2473
+ type: "textarea",
2474
+ required: false,
2475
+ placeholder: "Descreva o que este guardrail valida..."
2476
+ },
2477
+ {
2478
+ id: "function",
2479
+ label: "Fun\xE7\xE3o",
2480
+ type: "function",
2481
+ required: true,
2482
+ typeable: false,
2483
+ handle: {
2484
+ type: "input",
2485
+ label: "Fun\xE7\xE3o",
2486
+ name: "function",
2487
+ fieldType: "function",
2488
+ acceptTypes: ["code", "http", "any"],
2489
+ maxConnections: 1
2490
+ }
2491
+ },
2492
+ {
2493
+ id: "action",
2494
+ label: "A\xE7\xE3o em Viola\xE7\xE3o",
2495
+ type: "select",
2496
+ required: true,
2497
+ defaultValue: "block",
2498
+ options: [
2499
+ { label: "Bloquear", value: "block" },
2500
+ { label: "Avisar (Warning)", value: "warn" },
2501
+ { label: "Modificar", value: "modify" },
2502
+ { label: "Escalar (Human-in-the-loop)", value: "escalate" }
2503
+ ]
2504
+ },
2505
+ {
2506
+ id: "guardrail",
2507
+ label: "Guardrail",
2508
+ type: "guardrail",
2509
+ required: true,
2510
+ typeable: false,
2511
+ handle: {
2512
+ type: "output",
2513
+ label: "Guardrail",
2514
+ name: "guardrail",
2515
+ fieldType: "guardrail"
2516
+ }
2517
+ }
2518
+ ]
2519
+ };
2520
+
2521
+ // src/nodes/guardrails/function/function.ts
2522
+ var FunctionGuardrailNodeFunction = async (inputs) => {
2523
+ const { fieldValues = {} } = inputs;
2524
+ const {
2525
+ name,
2526
+ phase,
2527
+ description,
2528
+ action,
2529
+ nodeFunction,
2530
+ nodeType,
2531
+ originalNodeData
2532
+ } = fieldValues;
2533
+ return {
2534
+ type: "function",
2535
+ name: name || "Function Guardrail",
2536
+ phase: phase || "after",
2537
+ description: description || "",
2538
+ action: action || "block",
2539
+ // Injected by executeWorkflow.ts
2540
+ nodeFunction,
2541
+ nodeType,
2542
+ originalNodeData
2543
+ };
2544
+ };
2545
+
2546
+ // src/nodes/guardrails/model/data.ts
2547
+ import { z as z16 } from "zod";
2548
+ var ModelGuardrailNodeSchema = z16.object({
2549
+ name: z16.string().describe("Nome do guardrail"),
2550
+ evaluationPrompt: z16.string().describe("Prompt de avalia\xE7\xE3o"),
2551
+ model: z16.any().describe("Modelo LLM para avalia\xE7\xE3o"),
2552
+ action: z16.enum(["block", "warn", "escalate"]).describe("A\xE7\xE3o em caso de viola\xE7\xE3o")
2553
+ });
2554
+ var ModelGuardrailNode = {
2555
+ label: "Model Guardrail",
2556
+ type: "ModelGuardrailNode",
2557
+ category: "step",
2558
+ description: "Usa um modelo de IA secund\xE1rio para avaliar a seguran\xE7a ou qualidade do conte\xFAdo",
2559
+ icon: "\u{1F9E0}\u{1F6E1}\uFE0F",
2560
+ group: "Guardrails",
2561
+ tags: {
2562
+ execution: "async",
2563
+ group: "Guardrails"
2564
+ },
2565
+ fields: [
2566
+ {
2567
+ id: "name",
2568
+ label: "Nome",
2569
+ type: "string",
2570
+ required: true,
2571
+ placeholder: "Ex: Safety Check"
2572
+ },
2573
+ {
2574
+ id: "evaluationPrompt",
2575
+ label: "Prompt de Avalia\xE7\xE3o",
2576
+ type: "textarea",
2577
+ required: true,
2578
+ placeholder: "Ex: Avalie se a resposta abaixo cont\xE9m discurso de \xF3dio ou ofensas. Responda apenas SAFE ou UNSAFE.",
2579
+ defaultValue: "Analise se o conte\xFAdo a seguir \xE9 apropriado, seguro e segue as pol\xEDticas de \xE9tica. Responda 'SAFE' se estiver tudo bem ou 'UNSAFE' caso contr\xE1rio.\n\nCONTE\xDADO:\n{{content}}"
2580
+ },
2581
+ {
2582
+ id: "model",
2583
+ label: "Modelo de Avalia\xE7\xE3o",
2584
+ type: "model",
2585
+ required: true,
2586
+ handle: {
2587
+ type: "input",
2588
+ label: "Modelo",
2589
+ name: "model",
2590
+ fieldType: "model",
2591
+ acceptTypes: ["model"],
2592
+ maxConnections: 1
2593
+ }
2594
+ },
2595
+ {
2596
+ id: "action",
2597
+ label: "A\xE7\xE3o em Viola\xE7\xE3o (UNSAFE)",
2598
+ type: "select",
2599
+ required: true,
2600
+ defaultValue: "block",
2601
+ options: [
2602
+ { label: "Bloquear Resposta", value: "block" },
2603
+ { label: "Avisar (Warning)", value: "warn" },
2604
+ { label: "Escalar (Human-in-the-loop)", value: "escalate" }
2605
+ ]
2606
+ },
2607
+ {
2608
+ id: "guardrail",
2609
+ label: "Guardrail",
2610
+ type: "guardrail",
2611
+ required: true,
2612
+ typeable: false,
2613
+ handle: {
2614
+ type: "output",
2615
+ label: "Guardrail",
2616
+ name: "guardrail",
2617
+ fieldType: "guardrail"
2618
+ }
2619
+ }
2620
+ ]
2621
+ };
2622
+
2623
+ // src/nodes/guardrails/model/function.ts
2624
+ var ModelGuardrailNodeFunction = async (inputs) => {
2625
+ const { fieldValues = {} } = inputs;
2626
+ const {
2627
+ name,
2628
+ evaluationPrompt,
2629
+ model,
2630
+ action
2631
+ } = fieldValues;
2632
+ return {
2633
+ type: "model",
2634
+ name: name || "Model Guardrail",
2635
+ evaluationPrompt: evaluationPrompt || "Avalie se este conte\xFAdo \xE9 seguro. Responda apenas SAFE ou UNSAFE.",
2636
+ model,
2637
+ action: action || "block"
2638
+ };
2639
+ };
2640
+
2063
2641
  // src/nodes/consts/nodes.ts
2064
2642
  var nodes = [
2065
2643
  ChatInputNode,
@@ -2082,7 +2660,11 @@ var nodes = [
2082
2660
  WhatsappSendTemplateNode,
2083
2661
  WhatsappSendMessageNode,
2084
2662
  WhatsappMessageTriggerNode,
2085
- CustomCodeNode
2663
+ CustomCodeNode,
2664
+ PromptGuardrailNode,
2665
+ RuleGuardrailNode,
2666
+ FunctionGuardrailNode,
2667
+ ModelGuardrailNode
2086
2668
  ];
2087
2669
  var nodes_default = nodes;
2088
2670
 
@@ -2200,7 +2782,11 @@ var nodeFunctions = {
2200
2782
  CustomCodeNode: NodeFunction,
2201
2783
  CustomNode: CustomNodeFunction,
2202
2784
  PostgresMemoryNode: PostgresMemoryNodeFunction,
2203
- RedisMemoryNode: RedisMemoryNodeFunction
2785
+ RedisMemoryNode: RedisMemoryNodeFunction,
2786
+ PromptGuardrailNode: PromptGuardrailNodeFunction,
2787
+ RuleGuardrailNode: RuleGuardrailNodeFunction,
2788
+ FunctionGuardrailNode: FunctionGuardrailNodeFunction,
2789
+ ModelGuardrailNode: ModelGuardrailNodeFunction
2204
2790
  };
2205
2791
  var node_functions_default = nodeFunctions;
2206
2792
 
@@ -2314,12 +2900,12 @@ var HttpPutInputNodeFunction = (params) => {
2314
2900
  };
2315
2901
 
2316
2902
  // src/nodes/inputs/http/put/schema.ts
2317
- import { z as z13 } from "zod";
2318
- var HttpPutInputNodeSchema = z13.object({
2903
+ import { z as z17 } from "zod";
2904
+ var HttpPutInputNodeSchema = z17.object({
2319
2905
  route: RouteSchema,
2320
- queryParams: z13.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2321
- headers: z13.array(HeaderSchema).optional().describe("Headers configuration"),
2322
- body: z13.array(BodyFieldSchema).optional().describe("Body fields configuration")
2906
+ queryParams: z17.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2907
+ headers: z17.array(HeaderSchema).optional().describe("Headers configuration"),
2908
+ body: z17.array(BodyFieldSchema).optional().describe("Body fields configuration")
2323
2909
  });
2324
2910
 
2325
2911
  // src/nodes/inputs/http/delete/data.ts
@@ -2411,11 +2997,11 @@ var HttpDeleteInputNodeFunction = async (params) => {
2411
2997
  };
2412
2998
 
2413
2999
  // src/nodes/inputs/http/delete/schema.ts
2414
- import { z as z14 } from "zod";
2415
- var HttpDeleteInputNodeSchema = z14.object({
3000
+ import { z as z18 } from "zod";
3001
+ var HttpDeleteInputNodeSchema = z18.object({
2416
3002
  route: RouteSchema,
2417
- queryParams: z14.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2418
- headers: z14.array(HeaderSchema).optional().describe("Headers configuration")
3003
+ queryParams: z18.array(QueryParamSchema).optional().describe("Query parameters configuration"),
3004
+ headers: z18.array(HeaderSchema).optional().describe("Headers configuration")
2419
3005
  });
2420
3006
 
2421
3007
  // src/nodes/inputs/http/patch/data.ts
@@ -2528,12 +3114,12 @@ var HttpPatchInputNodeFunction = (params) => {
2528
3114
  };
2529
3115
 
2530
3116
  // src/nodes/inputs/http/patch/schema.ts
2531
- import { z as z15 } from "zod";
2532
- var HttpPatchInputNodeSchema = z15.object({
3117
+ import { z as z19 } from "zod";
3118
+ var HttpPatchInputNodeSchema = z19.object({
2533
3119
  route: RouteSchema,
2534
- queryParams: z15.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2535
- headers: z15.array(HeaderSchema).optional().describe("Headers configuration"),
2536
- body: z15.array(BodyFieldSchema).optional().describe("Body fields configuration")
3120
+ queryParams: z19.array(QueryParamSchema).optional().describe("Query parameters configuration"),
3121
+ headers: z19.array(HeaderSchema).optional().describe("Headers configuration"),
3122
+ body: z19.array(BodyFieldSchema).optional().describe("Body fields configuration")
2537
3123
  });
2538
3124
 
2539
3125
  // src/nodes/inputs/http/utils.ts