@atomoz/workflows-nodes 0.1.19 → 0.1.20

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
@@ -890,6 +890,21 @@ var IaAgentNode = {
890
890
  fieldType: "agent"
891
891
  }
892
892
  },
893
+ {
894
+ id: "sessionMemory",
895
+ label: "Session Memory",
896
+ type: "memory",
897
+ required: false,
898
+ typeable: false,
899
+ handle: {
900
+ type: "input",
901
+ label: "Session Memory",
902
+ name: "sessionMemory",
903
+ fieldType: "memory",
904
+ acceptTypes: ["memory"],
905
+ maxConnections: 1
906
+ }
907
+ },
893
908
  {
894
909
  id: "response",
895
910
  label: "Response",
@@ -969,10 +984,14 @@ async function createLLMFromModel(modelConfig, authToken, streaming = false) {
969
984
  // src/nodes/ia/agent/function.ts
970
985
  var IaAgentNodeFunction = async (inputs) => {
971
986
  const { $field: _$field, $req: _$req, $inputs: _$inputs, $vars: _$vars } = inputs;
972
- const { model, tools, systemMessage, name, message } = inputs.fieldValues || {};
987
+ const fieldValues = inputs.fieldValues || {};
988
+ const { model, tools, systemMessage, name, message } = fieldValues;
973
989
  const authToken = inputs.authToken;
974
990
  const stream = Boolean(inputs?.stream);
975
991
  const emitter = inputs?.emitter;
992
+ const sessionMemory = fieldValues.sessionMemory || inputs.sessionMemory;
993
+ const checkpointer = sessionMemory?.checkpointer;
994
+ const sessionId = inputs.sessionId || inputs.$req?.sessionId || `session-${Date.now()}`;
976
995
  if (!name) {
977
996
  throw new Error("Agent 'name' is required. Please provide a unique name for the agent in the node properties.");
978
997
  }
@@ -1003,17 +1022,26 @@ IMPORTANT: You must base your response on the last message in the conversation h
1003
1022
  const agent = createReactAgent({
1004
1023
  llm: llmInstance,
1005
1024
  tools: toolsArray,
1006
- messageModifier: finalSystemMessage
1025
+ messageModifier: finalSystemMessage,
1026
+ // Pass checkpointer directly for distributed memory
1027
+ ...checkpointer ? { checkpointer } : {}
1007
1028
  });
1008
1029
  agent.name = name;
1030
+ if (checkpointer) {
1031
+ console.log(`\u{1F9E0} IaAgentNode "${name}": Using distributed memory (sessionId: ${sessionId})`);
1032
+ } else {
1033
+ console.log(`\u26A0\uFE0F IaAgentNode "${name}": No sessionMemory connected - stateless mode`);
1034
+ }
1009
1035
  let output = "";
1010
1036
  if (message) {
1011
1037
  try {
1012
1038
  const { HumanMessage: HumanMessage2 } = await import("@langchain/core/messages");
1039
+ const invokeConfig = checkpointer ? { configurable: { thread_id: sessionId } } : {};
1013
1040
  if (stream && emitter) {
1014
- const streamIterator = await agent.stream({
1015
- messages: [new HumanMessage2(message)]
1016
- });
1041
+ const streamIterator = await agent.stream(
1042
+ { messages: [new HumanMessage2(message)] },
1043
+ invokeConfig
1044
+ );
1017
1045
  let lastMessages = [];
1018
1046
  const sentContents = /* @__PURE__ */ new Set();
1019
1047
  for await (const step of streamIterator) {
@@ -1057,9 +1085,10 @@ IMPORTANT: You must base your response on the last message in the conversation h
1057
1085
  }
1058
1086
  }
1059
1087
  } else {
1060
- const result = await agent.invoke({
1061
- messages: [new HumanMessage2(message)]
1062
- });
1088
+ const result = await agent.invoke(
1089
+ { messages: [new HumanMessage2(message)] },
1090
+ invokeConfig
1091
+ );
1063
1092
  if (result?.messages && result.messages.length > 0) {
1064
1093
  const lastMessage = result.messages[result.messages.length - 1];
1065
1094
  const content = lastMessage?.content;
@@ -1157,6 +1186,21 @@ var AiSupervisorNode = {
1157
1186
  acceptTypes: ["agent"]
1158
1187
  }
1159
1188
  },
1189
+ {
1190
+ id: "sessionMemory",
1191
+ label: "Session Memory",
1192
+ type: "memory",
1193
+ required: false,
1194
+ typeable: false,
1195
+ handle: {
1196
+ type: "input",
1197
+ label: "Session Memory",
1198
+ name: "sessionMemory",
1199
+ fieldType: "memory",
1200
+ acceptTypes: ["memory"],
1201
+ maxConnections: 1
1202
+ }
1203
+ },
1160
1204
  {
1161
1205
  id: "response",
1162
1206
  label: "Response",
@@ -1176,8 +1220,7 @@ var AiSupervisorNode = {
1176
1220
  // src/nodes/ia/supervisor/function.ts
1177
1221
  import { createSupervisor } from "@langchain/langgraph-supervisor";
1178
1222
  import { HumanMessage } from "@langchain/core/messages";
1179
- import { InMemoryStore, MemorySaver } from "@langchain/langgraph";
1180
- var checkpointer = new MemorySaver();
1223
+ import { InMemoryStore } from "@langchain/langgraph";
1181
1224
  var store = new InMemoryStore();
1182
1225
  var extractSupervisorAgents = (agents) => {
1183
1226
  if (Array.isArray(agents)) {
@@ -1233,6 +1276,9 @@ var AiSupervisorNodeFunction = async (params) => {
1233
1276
  const stream = (typeof outer.stream === "boolean" ? outer.stream : inner.stream) ?? false;
1234
1277
  const emitter = outer.emitter ?? inner.emitter;
1235
1278
  const authToken = outer.authToken ?? inner.authToken;
1279
+ const sessionMemory = inner.sessionMemory ?? outer.sessionMemory;
1280
+ const checkpointer = sessionMemory?.checkpointer;
1281
+ const sessionId = outer.sessionId || outer.$req?.sessionId || `supervisor-${Date.now()}`;
1236
1282
  if (!model) throw new Error("Model is required for AiSupervisorNode");
1237
1283
  if (!agents) throw new Error("Agents are required for AiSupervisorNode.");
1238
1284
  try {
@@ -1242,12 +1288,17 @@ var AiSupervisorNodeFunction = async (params) => {
1242
1288
  let llmInstance;
1243
1289
  if (model?.model && model?.integrationId) {
1244
1290
  if (!authToken) {
1245
- throw new Error("Auth token is required to instantiate LLM from integration 3");
1291
+ throw new Error("Auth token is required to instantiate LLM from integration");
1246
1292
  }
1247
1293
  llmInstance = await createLLMFromModel(model, authToken, stream);
1248
1294
  } else {
1249
1295
  llmInstance = model;
1250
1296
  }
1297
+ if (checkpointer) {
1298
+ console.log(`\u{1F9E0} AiSupervisorNode: Using distributed memory (sessionId: ${sessionId})`);
1299
+ } else {
1300
+ console.log(`\u26A0\uFE0F AiSupervisorNode: No sessionMemory connected - stateless mode`);
1301
+ }
1251
1302
  const finalSystemPrompt = systemMessage || "You are a supervisor...";
1252
1303
  const workflow = createSupervisor({
1253
1304
  llm: llmInstance,
@@ -1255,14 +1306,14 @@ var AiSupervisorNodeFunction = async (params) => {
1255
1306
  prompt: finalSystemPrompt
1256
1307
  });
1257
1308
  const app = workflow.compile({
1258
- checkpointer,
1309
+ ...checkpointer ? { checkpointer } : {},
1259
1310
  store
1260
1311
  });
1261
1312
  if (stream && emitter) {
1262
1313
  try {
1263
1314
  const streamIterator = await app.stream(
1264
1315
  { messages: [new HumanMessage({ content: message })] },
1265
- { recursionLimit: 150, configurable: { thread_id: "conversation" } }
1316
+ { recursionLimit: 150, configurable: { thread_id: sessionId } }
1266
1317
  );
1267
1318
  let finalMessages = [];
1268
1319
  const previousStepMessages = /* @__PURE__ */ new Map();
@@ -1341,7 +1392,7 @@ var AiSupervisorNodeFunction = async (params) => {
1341
1392
  } else {
1342
1393
  const result = await app.invoke(
1343
1394
  { messages: [new HumanMessage({ content: message })] },
1344
- { recursionLimit: 150, configurable: { thread_id: "conversation" } }
1395
+ { recursionLimit: 150, configurable: { thread_id: sessionId } }
1345
1396
  );
1346
1397
  const finalResponse = extractFinalResponse(result?.messages);
1347
1398
  return {
@@ -1435,12 +1486,139 @@ var AiToolNode = {
1435
1486
  // src/nodes/ia/tool/function.ts
1436
1487
  import { tool } from "@langchain/core/tools";
1437
1488
 
1489
+ // src/nodes/memory/postgres/data.ts
1490
+ import { z as z8 } from "zod";
1491
+ var PostgresMemoryNodeSchema = z8.object({
1492
+ connectionString: z8.string().describe("PostgreSQL connection string")
1493
+ });
1494
+ var PostgresMemoryNode = {
1495
+ label: "Postgres Memory",
1496
+ type: "PostgresMemoryNode",
1497
+ category: "memory",
1498
+ description: "Persistent conversation memory using PostgreSQL (distributed across pods)",
1499
+ icon: "\u{1F418}",
1500
+ group: "Memory",
1501
+ tags: {
1502
+ execution: "sync",
1503
+ group: "Memory"
1504
+ },
1505
+ fields: [
1506
+ {
1507
+ id: "connectionString",
1508
+ label: "Connection String",
1509
+ type: "string",
1510
+ required: true,
1511
+ defaultValue: "postgresql://postgres:postgres@localhost:5432/workflows",
1512
+ placeholder: "postgresql://user:pass@host:5432/database"
1513
+ },
1514
+ {
1515
+ id: "checkpointer",
1516
+ label: "Checkpointer",
1517
+ type: "memory",
1518
+ required: true,
1519
+ typeable: false,
1520
+ handle: {
1521
+ type: "output",
1522
+ label: "Memory",
1523
+ name: "checkpointer",
1524
+ fieldType: "memory"
1525
+ }
1526
+ }
1527
+ ]
1528
+ };
1529
+
1530
+ // src/nodes/memory/postgres/function.ts
1531
+ import { PostgresSaver } from "@langchain/langgraph-checkpoint-postgres";
1532
+ var PostgresMemoryNodeFunction = async (inputs) => {
1533
+ const { $field: _$field, $req: _$req, $inputs: _$inputs, $vars: _$vars } = inputs;
1534
+ const fieldValues = inputs.fieldValues || {};
1535
+ const connectionString = fieldValues.connectionString || inputs.connectionString || "postgresql://postgres:postgres@localhost:5432/workflows";
1536
+ try {
1537
+ const checkpointer = PostgresSaver.fromConnString(connectionString);
1538
+ await checkpointer.setup();
1539
+ console.log("\u2705 PostgresMemory: Checkpointer initialized");
1540
+ return {
1541
+ checkpointer,
1542
+ type: "PostgresMemoryNode",
1543
+ connectionString: connectionString.replace(/:[^:@]+@/, ":***@")
1544
+ // Hide password in output
1545
+ };
1546
+ } catch (error) {
1547
+ console.error("\u274C PostgresMemory: Failed to initialize checkpointer:", error);
1548
+ throw new Error(`PostgresMemory initialization failed: ${error instanceof Error ? error.message : String(error)}`);
1549
+ }
1550
+ };
1551
+
1552
+ // src/nodes/memory/redis/data.ts
1553
+ import { z as z9 } from "zod";
1554
+ var RedisMemoryNodeSchema = z9.object({
1555
+ redisUrl: z9.string().describe("Redis connection URL")
1556
+ });
1557
+ var RedisMemoryNode = {
1558
+ label: "Redis Memory",
1559
+ type: "RedisMemoryNode",
1560
+ category: "memory",
1561
+ description: "Fast, persistent conversation memory using Redis (distributed across pods)",
1562
+ icon: "\u{1F534}",
1563
+ group: "Memory",
1564
+ tags: {
1565
+ execution: "sync",
1566
+ group: "Memory"
1567
+ },
1568
+ fields: [
1569
+ {
1570
+ id: "redisUrl",
1571
+ label: "Redis URL",
1572
+ type: "string",
1573
+ required: true,
1574
+ defaultValue: "redis://localhost:6379",
1575
+ placeholder: "redis://localhost:6379"
1576
+ },
1577
+ {
1578
+ id: "checkpointer",
1579
+ label: "Checkpointer",
1580
+ type: "memory",
1581
+ required: true,
1582
+ typeable: false,
1583
+ handle: {
1584
+ type: "output",
1585
+ label: "Memory",
1586
+ name: "checkpointer",
1587
+ fieldType: "memory"
1588
+ }
1589
+ }
1590
+ ]
1591
+ };
1592
+
1593
+ // src/nodes/memory/redis/function.ts
1594
+ import { RedisSaver } from "@langchain/langgraph-checkpoint-redis";
1595
+ var RedisMemoryNodeFunction = async (inputs) => {
1596
+ const { $field: _$field, $req: _$req, $inputs: _$inputs, $vars: _$vars } = inputs;
1597
+ const fieldValues = inputs.fieldValues || {};
1598
+ const redisUrl = fieldValues.redisUrl || inputs.redisUrl || "redis://localhost:6379";
1599
+ try {
1600
+ const checkpointer = await RedisSaver.fromUrl(redisUrl);
1601
+ console.log("\u2705 RedisMemory: Checkpointer initialized");
1602
+ return {
1603
+ checkpointer,
1604
+ type: "RedisMemoryNode",
1605
+ redisUrl: redisUrl.replace(/:[^:@]+@/, ":***@")
1606
+ // Hide password in output
1607
+ };
1608
+ } catch (error) {
1609
+ console.error("\u274C RedisMemory: Failed to initialize checkpointer:", error);
1610
+ throw new Error(`RedisMemory initialization failed: ${error instanceof Error ? error.message : String(error)}`);
1611
+ }
1612
+ };
1613
+
1438
1614
  // src/nodes/consts/schemas.ts
1439
1615
  var schemas = {
1440
1616
  IaAgentNode: IaAgentNodeSchema,
1441
1617
  AiSupervisorNode: AiSupervisorNodeSchema,
1442
1618
  AiToolNode: AiToolNodeSchema,
1443
- IaMessageNode: IaMessageNodeSchema
1619
+ IaMessageNode: IaMessageNodeSchema,
1620
+ PostgresMemoryNode: PostgresMemoryNodeSchema,
1621
+ RedisMemoryNode: RedisMemoryNodeSchema
1444
1622
  };
1445
1623
 
1446
1624
  // src/nodes/ia/tool/function.ts
@@ -1482,11 +1660,11 @@ var AiToolNodeFunction = async (params) => {
1482
1660
  };
1483
1661
 
1484
1662
  // src/nodes/ia/message/message.ts
1485
- import { z as z8 } from "zod";
1486
- var IaMessageNodeSchema = z8.object({
1487
- model: z8.any().describe("LLM model to use"),
1488
- systemMessage: z8.string().optional().describe("System message for context"),
1489
- message: z8.string().describe("User message to send to the LLM")
1663
+ import { z as z10 } from "zod";
1664
+ var IaMessageNodeSchema = z10.object({
1665
+ model: z10.any().describe("LLM model to use"),
1666
+ systemMessage: z10.string().optional().describe("System message for context"),
1667
+ message: z10.string().describe("User message to send to the LLM")
1490
1668
  });
1491
1669
  var IaMessageNodeFunction = async (inputs) => {
1492
1670
  const { $field: _$field, $req: _$req, $inputs: _$inputs_var, $vars: _$vars } = inputs;
@@ -1621,10 +1799,10 @@ var IaMessageNode = {
1621
1799
  };
1622
1800
 
1623
1801
  // src/nodes/social/whatsapp/send-template/data.ts
1624
- import { z as z9 } from "zod";
1625
- var WhatsappSendTemplateNodeSchema = z9.object({
1626
- phoneNumber: z9.string().describe("Phone number to send the message to"),
1627
- message: z9.string().describe("Message to send")
1802
+ import { z as z11 } from "zod";
1803
+ var WhatsappSendTemplateNodeSchema = z11.object({
1804
+ phoneNumber: z11.string().describe("Phone number to send the message to"),
1805
+ message: z11.string().describe("Message to send")
1628
1806
  });
1629
1807
  var WhatsappSendTemplateNode = {
1630
1808
  label: "Whatsapp Send Template",
@@ -1665,10 +1843,10 @@ var WhatsappSendTemplateNode = {
1665
1843
  };
1666
1844
 
1667
1845
  // src/nodes/social/whatsapp/send-message/data.ts
1668
- import { z as z10 } from "zod";
1669
- var WhatsappSendMessageNodeSchema = z10.object({
1670
- phoneNumber: z10.string().describe("Phone number to send the message to"),
1671
- message: z10.string().describe("Message content to send")
1846
+ import { z as z12 } from "zod";
1847
+ var WhatsappSendMessageNodeSchema = z12.object({
1848
+ phoneNumber: z12.string().describe("Phone number to send the message to"),
1849
+ message: z12.string().describe("Message content to send")
1672
1850
  });
1673
1851
  var WhatsappSendMessageNode = {
1674
1852
  label: "Whatsapp Send Message",
@@ -1899,6 +2077,8 @@ var nodes = [
1899
2077
  IaAgentNode,
1900
2078
  AiToolNode,
1901
2079
  AiSupervisorNode,
2080
+ PostgresMemoryNode,
2081
+ RedisMemoryNode,
1902
2082
  WhatsappSendTemplateNode,
1903
2083
  WhatsappSendMessageNode,
1904
2084
  WhatsappMessageTriggerNode,
@@ -2018,7 +2198,9 @@ var nodeFunctions = {
2018
2198
  WhatsappNode: WhatsappStartChatFunction,
2019
2199
  WhatsappSendMessageNode: WhatsappSendMessageFunction,
2020
2200
  CustomCodeNode: NodeFunction,
2021
- CustomNode: CustomNodeFunction
2201
+ CustomNode: CustomNodeFunction,
2202
+ PostgresMemoryNode: PostgresMemoryNodeFunction,
2203
+ RedisMemoryNode: RedisMemoryNodeFunction
2022
2204
  };
2023
2205
  var node_functions_default = nodeFunctions;
2024
2206
 
@@ -2132,12 +2314,12 @@ var HttpPutInputNodeFunction = (params) => {
2132
2314
  };
2133
2315
 
2134
2316
  // src/nodes/inputs/http/put/schema.ts
2135
- import { z as z11 } from "zod";
2136
- var HttpPutInputNodeSchema = z11.object({
2317
+ import { z as z13 } from "zod";
2318
+ var HttpPutInputNodeSchema = z13.object({
2137
2319
  route: RouteSchema,
2138
- queryParams: z11.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2139
- headers: z11.array(HeaderSchema).optional().describe("Headers configuration"),
2140
- body: z11.array(BodyFieldSchema).optional().describe("Body fields configuration")
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")
2141
2323
  });
2142
2324
 
2143
2325
  // src/nodes/inputs/http/delete/data.ts
@@ -2229,11 +2411,11 @@ var HttpDeleteInputNodeFunction = async (params) => {
2229
2411
  };
2230
2412
 
2231
2413
  // src/nodes/inputs/http/delete/schema.ts
2232
- import { z as z12 } from "zod";
2233
- var HttpDeleteInputNodeSchema = z12.object({
2414
+ import { z as z14 } from "zod";
2415
+ var HttpDeleteInputNodeSchema = z14.object({
2234
2416
  route: RouteSchema,
2235
- queryParams: z12.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2236
- headers: z12.array(HeaderSchema).optional().describe("Headers configuration")
2417
+ queryParams: z14.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2418
+ headers: z14.array(HeaderSchema).optional().describe("Headers configuration")
2237
2419
  });
2238
2420
 
2239
2421
  // src/nodes/inputs/http/patch/data.ts
@@ -2346,12 +2528,12 @@ var HttpPatchInputNodeFunction = (params) => {
2346
2528
  };
2347
2529
 
2348
2530
  // src/nodes/inputs/http/patch/schema.ts
2349
- import { z as z13 } from "zod";
2350
- var HttpPatchInputNodeSchema = z13.object({
2531
+ import { z as z15 } from "zod";
2532
+ var HttpPatchInputNodeSchema = z15.object({
2351
2533
  route: RouteSchema,
2352
- queryParams: z13.array(QueryParamSchema).optional().describe("Query parameters configuration"),
2353
- headers: z13.array(HeaderSchema).optional().describe("Headers configuration"),
2354
- body: z13.array(BodyFieldSchema).optional().describe("Body fields configuration")
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")
2355
2537
  });
2356
2538
 
2357
2539
  // src/nodes/inputs/http/utils.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atomoz/workflows-nodes",
3
- "version": "0.1.19",
3
+ "version": "0.1.20",
4
4
  "description": "Atomoz Workflows - Node Library",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,8 +32,8 @@
32
32
  "author": "Atomoz",
33
33
  "license": "MIT",
34
34
  "scripts": {
35
- "build": "tsup index.ts --dts --format esm,cjs --target node18 --out-dir dist --clean --tsconfig tsconfig.build.json",
36
- "dev": "tsup index.ts --dts --format esm,cjs --target node18 --out-dir dist --watch --tsconfig tsconfig.build.json"
35
+ "build": "tsup",
36
+ "dev": "tsup --watch"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "zod": ">=3.0.0 || >=4.0.0"
@@ -42,11 +42,14 @@
42
42
  "@langchain/core": "^0.3.66",
43
43
  "@langchain/google-gauth": "^0.2.16",
44
44
  "@langchain/langgraph": "^0.4.3",
45
+ "@langchain/langgraph-checkpoint-postgres": "^1.0.0",
46
+ "@langchain/langgraph-checkpoint-redis": "^1.0.1",
45
47
  "@langchain/langgraph-supervisor": "^0.0.17",
46
48
  "@langchain/openai": "^0.6.3",
47
49
  "graphql-request": "^7.2.0"
48
50
  },
49
51
  "devDependencies": {
52
+ "@types/node": "^25.0.3",
50
53
  "tsup": "^8.2.4",
51
54
  "typescript": "^5.6.3",
52
55
  "zod": "^4.0.14"