@loomcycle/n8n-nodes-loomcycle 1.0.0

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 (99) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +190 -0
  3. package/dist/credentials/LoomCycleApi.credentials.d.ts +21 -0
  4. package/dist/credentials/LoomCycleApi.credentials.js +81 -0
  5. package/dist/credentials/LoomCycleApi.credentials.js.map +1 -0
  6. package/dist/nodes/LoomCycle/LoomCycle.node.d.ts +22 -0
  7. package/dist/nodes/LoomCycle/LoomCycle.node.js +403 -0
  8. package/dist/nodes/LoomCycle/LoomCycle.node.js.map +1 -0
  9. package/dist/nodes/LoomCycle/LoomCycle.node.json +13 -0
  10. package/dist/nodes/LoomCycle/LoomCycle.svg +13 -0
  11. package/dist/nodes/LoomCycle/descriptions/agentdef.d.ts +21 -0
  12. package/dist/nodes/LoomCycle/descriptions/agentdef.js +155 -0
  13. package/dist/nodes/LoomCycle/descriptions/agentdef.js.map +1 -0
  14. package/dist/nodes/LoomCycle/descriptions/channels.d.ts +19 -0
  15. package/dist/nodes/LoomCycle/descriptions/channels.js +164 -0
  16. package/dist/nodes/LoomCycle/descriptions/channels.js.map +1 -0
  17. package/dist/nodes/LoomCycle/descriptions/index.d.ts +6 -0
  18. package/dist/nodes/LoomCycle/descriptions/index.js +16 -0
  19. package/dist/nodes/LoomCycle/descriptions/index.js.map +1 -0
  20. package/dist/nodes/LoomCycle/descriptions/mcpserverdef.d.ts +29 -0
  21. package/dist/nodes/LoomCycle/descriptions/mcpserverdef.js +241 -0
  22. package/dist/nodes/LoomCycle/descriptions/mcpserverdef.js.map +1 -0
  23. package/dist/nodes/LoomCycle/descriptions/memory.d.ts +20 -0
  24. package/dist/nodes/LoomCycle/descriptions/memory.js +119 -0
  25. package/dist/nodes/LoomCycle/descriptions/memory.js.map +1 -0
  26. package/dist/nodes/LoomCycle/descriptions/runs.d.ts +17 -0
  27. package/dist/nodes/LoomCycle/descriptions/runs.js +226 -0
  28. package/dist/nodes/LoomCycle/descriptions/runs.js.map +1 -0
  29. package/dist/nodes/LoomCycle/descriptions/skilldef.d.ts +10 -0
  30. package/dist/nodes/LoomCycle/descriptions/skilldef.js +144 -0
  31. package/dist/nodes/LoomCycle/descriptions/skilldef.js.map +1 -0
  32. package/dist/nodes/LoomCycle/helpers/capability.d.ts +42 -0
  33. package/dist/nodes/LoomCycle/helpers/capability.js +54 -0
  34. package/dist/nodes/LoomCycle/helpers/capability.js.map +1 -0
  35. package/dist/nodes/LoomCycle/helpers/client.d.ts +15 -0
  36. package/dist/nodes/LoomCycle/helpers/client.js +30 -0
  37. package/dist/nodes/LoomCycle/helpers/client.js.map +1 -0
  38. package/dist/nodes/LoomCycle/helpers/envVarHints.d.ts +30 -0
  39. package/dist/nodes/LoomCycle/helpers/envVarHints.js +67 -0
  40. package/dist/nodes/LoomCycle/helpers/envVarHints.js.map +1 -0
  41. package/dist/nodes/LoomCycle/helpers/errors.d.ts +23 -0
  42. package/dist/nodes/LoomCycle/helpers/errors.js +189 -0
  43. package/dist/nodes/LoomCycle/helpers/errors.js.map +1 -0
  44. package/dist/nodes/LoomCycle/helpers/loadOptions.d.ts +24 -0
  45. package/dist/nodes/LoomCycle/helpers/loadOptions.js +89 -0
  46. package/dist/nodes/LoomCycle/helpers/loadOptions.js.map +1 -0
  47. package/dist/nodes/LoomCycle/helpers/segments.d.ts +13 -0
  48. package/dist/nodes/LoomCycle/helpers/segments.js +31 -0
  49. package/dist/nodes/LoomCycle/helpers/segments.js.map +1 -0
  50. package/dist/nodes/LoomCycle/helpers/staticData.d.ts +5 -0
  51. package/dist/nodes/LoomCycle/helpers/staticData.js +31 -0
  52. package/dist/nodes/LoomCycle/helpers/staticData.js.map +1 -0
  53. package/dist/nodes/LoomCycle/helpers/streaming.d.ts +31 -0
  54. package/dist/nodes/LoomCycle/helpers/streaming.js +48 -0
  55. package/dist/nodes/LoomCycle/helpers/streaming.js.map +1 -0
  56. package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.d.ts +24 -0
  57. package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.js +162 -0
  58. package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.js.map +1 -0
  59. package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.json +13 -0
  60. package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.svg +9 -0
  61. package/dist/nodes/LoomCycleChannelMessage/helpers/subscribe.d.ts +20 -0
  62. package/dist/nodes/LoomCycleChannelMessage/helpers/subscribe.js +106 -0
  63. package/dist/nodes/LoomCycleChannelMessage/helpers/subscribe.js.map +1 -0
  64. package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.d.ts +5 -0
  65. package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.js +114 -0
  66. package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.js.map +1 -0
  67. package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.json +13 -0
  68. package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.svg +13 -0
  69. package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.d.ts +5 -0
  70. package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.js +259 -0
  71. package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.js.map +1 -0
  72. package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.json +13 -0
  73. package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.svg +14 -0
  74. package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.d.ts +5 -0
  75. package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.js +108 -0
  76. package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.js.map +1 -0
  77. package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.json +13 -0
  78. package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.svg +11 -0
  79. package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.d.ts +18 -0
  80. package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.js +188 -0
  81. package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.js.map +1 -0
  82. package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.json +13 -0
  83. package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.svg +10 -0
  84. package/dist/nodes/LoomCycleRunCompleted/helpers/poll.d.ts +12 -0
  85. package/dist/nodes/LoomCycleRunCompleted/helpers/poll.js +69 -0
  86. package/dist/nodes/LoomCycleRunCompleted/helpers/poll.js.map +1 -0
  87. package/dist/nodes/LoomCycleRunCompleted/helpers/sse.d.ts +29 -0
  88. package/dist/nodes/LoomCycleRunCompleted/helpers/sse.js +61 -0
  89. package/dist/nodes/LoomCycleRunCompleted/helpers/sse.js.map +1 -0
  90. package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.d.ts +5 -0
  91. package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.js +131 -0
  92. package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.js.map +1 -0
  93. package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.json +13 -0
  94. package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.svg +12 -0
  95. package/dist/nodes/_shared/clusterTool.d.ts +19 -0
  96. package/dist/nodes/_shared/clusterTool.js +36 -0
  97. package/dist/nodes/_shared/clusterTool.js.map +1 -0
  98. package/dist/tsconfig.tsbuildinfo +1 -0
  99. package/package.json +86 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoomCycleRunCompleted.node.js","sourceRoot":"","sources":["../../../nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ {
2
+ "node": "@loomcycle/n8n-nodes-loomcycle.loomCycleRunCompleted",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": ["AI"],
6
+ "resources": {
7
+ "primaryDocumentation": [
8
+ {
9
+ "url": "https://github.com/denn-gubsky/n8n-nodes-loomcycle#trigger-nodes"
10
+ }
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,10 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60">
3
+ <title>LoomCycle: Run Completed</title>
4
+ <circle cx="30" cy="30" r="28" fill="#0f172a"/>
5
+ <g fill="none" stroke="#22d3ee" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
6
+ <circle cx="30" cy="30" r="16"/>
7
+ <path d="M22 30 L28 36 L40 22"/>
8
+ </g>
9
+ <circle cx="30" cy="30" r="3" fill="#22d3ee"/>
10
+ </svg>
@@ -0,0 +1,12 @@
1
+ import type { ITriggerFunctions } from 'n8n-workflow';
2
+ import type { AgentStatus, LoomcycleClient } from '@loomcycle/client';
3
+ export interface PollOptions {
4
+ client: LoomcycleClient;
5
+ userId: string;
6
+ statuses: AgentStatus[];
7
+ parentAgentId?: string;
8
+ intervalMs: number;
9
+ signal: AbortSignal;
10
+ }
11
+ export declare function runPollLoop(this: ITriggerFunctions, opts: PollOptions): Promise<void>;
12
+ export declare function pollOnce(this: ITriggerFunctions, opts: PollOptions): Promise<void>;
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runPollLoop = runPollLoop;
4
+ exports.pollOnce = pollOnce;
5
+ const staticData_1 = require("../../LoomCycle/helpers/staticData");
6
+ /**
7
+ * Polling-fallback event loop for the LoomCycleRunCompleted trigger.
8
+ *
9
+ * Calls `listUserAgents(userId, { status, parentAgentId? })` on a fixed
10
+ * interval, dedups against `workflowStaticData[seenKey].seen` (a set of
11
+ * agent_ids), emits any new rows whose status matches the operator's
12
+ * filter. Terminal statuses go into the seen set; running rows are
13
+ * skipped (we want the COMPLETION emit, not in-flight emits).
14
+ *
15
+ * Used when the operator's deployment can't sustain a long-lived SSE
16
+ * connection (Cloudflare workers without WebSocket, naive nginx
17
+ * `proxy_buffering on`, etc.).
18
+ */
19
+ const SEEN_KEY = 'runCompletedSeen';
20
+ async function runPollLoop(opts) {
21
+ while (!opts.signal.aborted) {
22
+ try {
23
+ await pollOnce.call(this, opts);
24
+ }
25
+ catch (err) {
26
+ if (opts.signal.aborted)
27
+ return;
28
+ this.emitError(err);
29
+ // fall through to wait then retry
30
+ }
31
+ await sleep(opts.intervalMs, opts.signal);
32
+ }
33
+ }
34
+ async function pollOnce(opts) {
35
+ // listUserAgents takes a single `status` filter; iterate the
36
+ // operator's selection. When empty, ask for all terminal statuses.
37
+ const wanted = opts.statuses.length > 0 ? opts.statuses : ['completed', 'failed', 'cancelled'];
38
+ const seen = (0, staticData_1.readSeenSet)(this, SEEN_KEY);
39
+ const fresh = [];
40
+ for (const status of wanted) {
41
+ const rows = await opts.client.listUserAgents(opts.userId, {
42
+ status,
43
+ parentAgentId: opts.parentAgentId,
44
+ signal: opts.signal,
45
+ });
46
+ for (const row of rows) {
47
+ if (!row.agent_id || seen.has(row.agent_id))
48
+ continue;
49
+ fresh.push(row);
50
+ seen.add(row.agent_id);
51
+ }
52
+ }
53
+ if (fresh.length > 0) {
54
+ (0, staticData_1.writeSeenSet)(this, SEEN_KEY, seen);
55
+ this.emit([this.helpers.returnJsonArray(fresh.map((r) => r))]);
56
+ }
57
+ }
58
+ function sleep(ms, signal) {
59
+ return new Promise((resolve) => {
60
+ if (signal.aborted)
61
+ return resolve();
62
+ const t = setTimeout(resolve, ms);
63
+ signal.addEventListener('abort', () => {
64
+ clearTimeout(t);
65
+ resolve();
66
+ });
67
+ });
68
+ }
69
+ //# sourceMappingURL=poll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poll.js","sourceRoot":"","sources":["../../../../nodes/LoomCycleRunCompleted/helpers/poll.ts"],"names":[],"mappings":";;AA6BA,kCAWC;AAED,4BAyBC;AAjED,mEAA+E;AAE/E;;;;;;;;;;;;GAYG;AAEH,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AAW7B,KAAK,UAAU,WAAW,CAA0B,IAAiB;IAC3E,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACJ,MAAM,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO;YAChC,IAAI,CAAC,SAAS,CAAC,GAAY,CAAC,CAAC;YAC7B,kCAAkC;QACnC,CAAC;QACD,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3C,CAAC;AACF,CAAC;AAEM,KAAK,UAAU,QAAQ,CAA0B,IAAiB;IACxE,6DAA6D;IAC7D,mEAAmE;IACnE,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAE,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAmB,CAAC;IAElH,MAAM,IAAI,GAAG,IAAA,wBAAW,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,KAAK,GAAY,EAAE,CAAC;IAE1B,KAAK,MAAM,MAAM,IAAI,MAAM,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE;YAC1D,MAAM;YACN,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,MAAM,EAAE,IAAI,CAAC,MAAM;SACnB,CAAC,CAAC;QACH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACtD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACxB,CAAC;IACF,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,IAAA,yBAAY,EAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAA2B,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,CAAC;AACF,CAAC;AAED,SAAS,KAAK,CAAC,EAAU,EAAE,MAAmB;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,OAAO,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACrC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,EAAE,CAAC;QACX,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type { ITriggerFunctions } from 'n8n-workflow';
2
+ import type { LoomcycleClient } from '@loomcycle/client';
3
+ /**
4
+ * SSE-driven event loop for the LoomCycleRunCompleted trigger.
5
+ *
6
+ * Wraps `client.streamUserRunStates(userId, opts)` in an auto-reconnect
7
+ * outer loop: when the iterator completes (server-side 30-min cap, or
8
+ * a transient disconnect), the loop re-opens unless the abort signal
9
+ * is fired.
10
+ *
11
+ * Adapter `debug: true` yields synthetic `{ kind: "close", payload:
12
+ * { reason } }` items around real frames; we emit those as debug rows
13
+ * so the operator can see reconnects when opted-in.
14
+ *
15
+ * On a non-abort error (network / 5xx / auth flip), the loop re-throws
16
+ * via emitError so the n8n trigger lifecycle handles it.
17
+ */
18
+ export interface SseOptions {
19
+ client: LoomcycleClient;
20
+ userId: string;
21
+ statuses: string[];
22
+ parentAgentId?: string;
23
+ agent?: string;
24
+ debug: boolean;
25
+ emitClose: boolean;
26
+ signal: AbortSignal;
27
+ reconnectBackoffMs: number;
28
+ }
29
+ export declare function runSseLoop(this: ITriggerFunctions, opts: SseOptions): Promise<void>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runSseLoop = runSseLoop;
4
+ async function runSseLoop(opts) {
5
+ let attempt = 0;
6
+ while (!opts.signal.aborted) {
7
+ try {
8
+ for await (const item of opts.client.streamUserRunStates(opts.userId, {
9
+ statuses: opts.statuses.length > 0 ? opts.statuses : undefined,
10
+ agent: opts.agent,
11
+ parentAgentId: opts.parentAgentId,
12
+ debug: opts.debug,
13
+ signal: opts.signal,
14
+ })) {
15
+ if (opts.signal.aborted)
16
+ return;
17
+ if (item.kind === 'event') {
18
+ this.emit([this.helpers.returnJsonArray([item.payload])]);
19
+ }
20
+ else if (item.kind === 'close' && opts.emitClose) {
21
+ this.emit([
22
+ this.helpers.returnJsonArray([
23
+ {
24
+ __meta: 'stream_close',
25
+ reason: item.payload?.reason ?? '',
26
+ },
27
+ ]),
28
+ ]);
29
+ }
30
+ }
31
+ attempt = 0; // clean stream end → reset backoff
32
+ }
33
+ catch (err) {
34
+ if (opts.signal.aborted)
35
+ return;
36
+ attempt += 1;
37
+ if (attempt >= 5) {
38
+ // Terminal — no more reconnects. emitError ONCE so n8n's
39
+ // trigger lifecycle deactivates rather than going silently
40
+ // deaf. Earlier attempts swallow the error + backoff because
41
+ // transient SSE drops are normal (30-min server cap,
42
+ // reverse-proxy idle resets, etc).
43
+ this.emitError(err);
44
+ return;
45
+ }
46
+ await sleep(opts.reconnectBackoffMs * Math.min(attempt, 4), opts.signal);
47
+ }
48
+ }
49
+ }
50
+ function sleep(ms, signal) {
51
+ return new Promise((resolve) => {
52
+ if (signal.aborted)
53
+ return resolve();
54
+ const t = setTimeout(resolve, ms);
55
+ signal.addEventListener('abort', () => {
56
+ clearTimeout(t);
57
+ resolve();
58
+ });
59
+ });
60
+ }
61
+ //# sourceMappingURL=sse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../../nodes/LoomCycleRunCompleted/helpers/sse.ts"],"names":[],"mappings":";;AA+BA,gCAyCC;AAzCM,KAAK,UAAU,UAAU,CAA0B,IAAgB;IACzE,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACJ,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,IAAI,CAAC,MAAM,CAAC,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE;gBACrE,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;gBAC9D,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,aAAa,EAAE,IAAI,CAAC,aAAa;gBACjC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,MAAM,EAAE,IAAI,CAAC,MAAM;aACnB,CAAC,EAAE,CAAC;gBACJ,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO;oBAAE,OAAO;gBAChC,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,IAAI,CAAC,OAAiC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrF,CAAC;qBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACpD,IAAI,CAAC,IAAI,CAAC;wBACT,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC;4BAC5B;gCACC,MAAM,EAAE,cAAc;gCACtB,MAAM,EAAG,IAA0C,CAAC,OAAO,EAAE,MAAM,IAAI,EAAE;6BAC1D;yBAChB,CAAC;qBACF,CAAC,CAAC;gBACJ,CAAC;YACF,CAAC;YACD,OAAO,GAAG,CAAC,CAAC,CAAC,mCAAmC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,IAAI,IAAI,CAAC,MAAM,CAAC,OAAO;gBAAE,OAAO;YAChC,OAAO,IAAI,CAAC,CAAC;YACb,IAAI,OAAO,IAAI,CAAC,EAAE,CAAC;gBAClB,yDAAyD;gBACzD,2DAA2D;gBAC3D,6DAA6D;gBAC7D,qDAAqD;gBACrD,mCAAmC;gBACnC,IAAI,CAAC,SAAS,CAAC,GAAY,CAAC,CAAC;gBAC7B,OAAO;YACR,CAAC;YACD,MAAM,KAAK,CAAC,IAAI,CAAC,kBAAkB,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;QAC1E,CAAC;IACF,CAAC;AACF,CAAC;AAED,SAAS,KAAK,CAAC,EAAU,EAAE,MAAmB;IAC7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC9B,IAAI,MAAM,CAAC,OAAO;YAAE,OAAO,OAAO,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClC,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE;YACrC,YAAY,CAAC,CAAC,CAAC,CAAC;YAChB,OAAO,EAAE,CAAC;QACX,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { INodeType, INodeTypeDescription, ISupplyDataFunctions, SupplyData } from 'n8n-workflow';
2
+ export declare class LoomCycleSubAgentTool implements INodeType {
3
+ description: INodeTypeDescription;
4
+ supplyData(this: ISupplyDataFunctions): Promise<SupplyData>;
5
+ }
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.LoomCycleSubAgentTool = void 0;
4
+ const n8n_workflow_1 = require("n8n-workflow");
5
+ const zod_1 = require("zod");
6
+ const client_1 = require("../LoomCycle/helpers/client");
7
+ const segments_1 = require("../LoomCycle/helpers/segments");
8
+ const streaming_1 = require("../LoomCycle/helpers/streaming");
9
+ const clusterTool_1 = require("../_shared/clusterTool");
10
+ /**
11
+ * `LoomCycle Sub-Agent Tool` — cluster sub-node that lets the parent
12
+ * n8n AI Agent delegate to a loomcycle agent. When the parent invokes
13
+ * the tool with a prompt, this node spawns the configured loomcycle
14
+ * agent, blocks until it terminates, and returns the drained final
15
+ * text.
16
+ *
17
+ * Useful for: handing off to a specialised loomcycle agent (code-
18
+ * generation, research, evaluation, etc.) while the n8n AI Agent
19
+ * remains the user-facing orchestrator.
20
+ */
21
+ const SubAgentInputSchema = zod_1.z.object({
22
+ prompt: zod_1.z.string().describe('Prompt sent to the loomcycle agent'),
23
+ sessionId: zod_1.z.string().optional().describe('Optional session_id to continue an existing session'),
24
+ });
25
+ class LoomCycleSubAgentTool {
26
+ constructor() {
27
+ this.description = {
28
+ displayName: 'LoomCycle Sub-Agent Tool',
29
+ name: 'loomCycleSubAgentTool',
30
+ icon: 'file:LoomCycleSubAgentTool.svg',
31
+ group: ['transform'],
32
+ version: 1,
33
+ description: 'Delegates to a configured loomcycle agent — the parent AI Agent calls this tool with a prompt',
34
+ defaults: { name: 'LoomCycle Sub-Agent Tool' },
35
+ codex: { categories: ['AI'], subcategories: { AI: ['Tools'] } },
36
+ // eslint-disable-next-line n8n-nodes-base/node-class-description-inputs-wrong-regular-node
37
+ inputs: [],
38
+ // eslint-disable-next-line n8n-nodes-base/node-class-description-outputs-wrong
39
+ outputs: [n8n_workflow_1.NodeConnectionTypes.AiTool],
40
+ outputNames: ['Tool'],
41
+ credentials: [{ name: 'loomCycleApi', required: true }],
42
+ properties: [
43
+ {
44
+ displayName: 'Tool Name',
45
+ name: 'toolName',
46
+ type: 'string',
47
+ default: 'loomcycle_sub_agent',
48
+ required: true,
49
+ description: 'Name of the tool surfaced to the parent AI Agent',
50
+ },
51
+ {
52
+ displayName: 'Tool Description',
53
+ name: 'toolDescription',
54
+ type: 'string',
55
+ typeOptions: { rows: 3 },
56
+ default: 'Delegate a task to a specialised loomcycle agent. Pass the task as the prompt; receive the agent\'s final text.',
57
+ description: 'Description the AI Agent sees when deciding whether to call the tool',
58
+ },
59
+ {
60
+ displayName: 'Agent Name or ID',
61
+ name: 'agent',
62
+ type: 'string',
63
+ default: '',
64
+ required: true,
65
+ description: 'Loomcycle agent name to spawn — must be declared in operator yaml or registered dynamically',
66
+ },
67
+ {
68
+ displayName: 'User ID',
69
+ name: 'userId',
70
+ type: 'string',
71
+ default: '',
72
+ description: 'Per-tool override of user_id. Falls through to credential default.',
73
+ },
74
+ {
75
+ displayName: 'User Tier',
76
+ name: 'userTier',
77
+ type: 'string',
78
+ default: '',
79
+ description: 'Per-tool override of user_tier. Falls through to credential default.',
80
+ },
81
+ {
82
+ displayName: 'Treat Prompt as Untrusted',
83
+ name: 'treatPromptAsUntrusted',
84
+ type: 'boolean',
85
+ default: true,
86
+ description: 'Whether to wrap the prompt as an untrusted-block segment. Defaults true here because the prompt is model-supplied (the parent AI Agent\'s tool-call argument).',
87
+ },
88
+ ],
89
+ };
90
+ }
91
+ async supplyData() {
92
+ const toolName = this.getNodeParameter('toolName', 0, 'loomcycle_sub_agent');
93
+ const toolDescription = this.getNodeParameter('toolDescription', 0, '');
94
+ const agent = this.getNodeParameter('agent', 0);
95
+ const userIdParam = this.getNodeParameter('userId', 0, '');
96
+ const userTierParam = this.getNodeParameter('userTier', 0, '');
97
+ const treatPromptAsUntrusted = this.getNodeParameter('treatPromptAsUntrusted', 0, true);
98
+ const client = await (0, client_1.getClient)(this);
99
+ const userIdDefault = await (0, client_1.getCredentialDefault)(this, 'userId');
100
+ const userTierDefault = await (0, client_1.getCredentialDefault)(this, 'userTier');
101
+ const userId = userIdParam || userIdDefault;
102
+ const userTier = userTierParam || userTierDefault;
103
+ const tool = (0, clusterTool_1.buildTool)({
104
+ name: toolName,
105
+ description: toolDescription,
106
+ schema: SubAgentInputSchema,
107
+ fn: async (args) => {
108
+ const runOpts = {
109
+ agent,
110
+ segments: (0, segments_1.buildSegments)(args.prompt, treatPromptAsUntrusted),
111
+ };
112
+ if (userId)
113
+ runOpts.userId = userId;
114
+ if (userTier)
115
+ runOpts.userTier = userTier;
116
+ if (args.sessionId)
117
+ runOpts.sessionId = args.sessionId;
118
+ const result = await (0, streaming_1.drainRunStream)(client.runStreaming(runOpts));
119
+ // Return the finalText directly (string contract) so the parent
120
+ // AI Agent treats it as the tool's textual output. Metadata
121
+ // like usage/sessionId/agentId are dropped — too noisy for the
122
+ // agent's context. Operators wanting those should use the
123
+ // action node's Spawn op instead.
124
+ return result.finalText;
125
+ },
126
+ });
127
+ return { response: tool };
128
+ }
129
+ }
130
+ exports.LoomCycleSubAgentTool = LoomCycleSubAgentTool;
131
+ //# sourceMappingURL=LoomCycleSubAgentTool.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LoomCycleSubAgentTool.node.js","sourceRoot":"","sources":["../../../nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ {
2
+ "node": "@loomcycle/n8n-nodes-loomcycle.loomCycleSubAgentTool",
3
+ "nodeVersion": "1.0",
4
+ "codexVersion": "1.0",
5
+ "categories": ["AI"],
6
+ "resources": {
7
+ "primaryDocumentation": [
8
+ {
9
+ "url": "https://github.com/denn-gubsky/n8n-nodes-loomcycle#cluster-sub-nodes"
10
+ }
11
+ ]
12
+ }
13
+ }
@@ -0,0 +1,12 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 60 60" width="60" height="60">
3
+ <title>LoomCycle Sub-Agent Tool</title>
4
+ <circle cx="30" cy="30" r="28" fill="#0f172a"/>
5
+ <g fill="none" stroke="#22d3ee" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round">
6
+ <circle cx="22" cy="22" r="6"/>
7
+ <circle cx="40" cy="22" r="4"/>
8
+ <circle cx="40" cy="38" r="4"/>
9
+ <path d="M27 23 L36 22"/>
10
+ <path d="M27 27 L36 36"/>
11
+ </g>
12
+ </svg>
@@ -0,0 +1,19 @@
1
+ import { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import type { z } from 'zod';
3
+ /**
4
+ * Build a LangChain `DynamicStructuredTool` with our standard error
5
+ * envelope. Every cluster sub-node uses this helper so the wire surface
6
+ * to the parent AI Agent is uniform.
7
+ *
8
+ * The returned tool's `func` always resolves to a string (LangChain
9
+ * contract). We JSON-stringify structured results; thrown wire errors
10
+ * are caught + redacted + returned as a `{"error": "..."}` string so
11
+ * the agent can read the failure mode without us leaking bearer
12
+ * fragments into the model's context (CLAUDE.md §security.6).
13
+ */
14
+ export declare function buildTool<S extends z.ZodTypeAny>(opts: {
15
+ name: string;
16
+ description: string;
17
+ schema: S;
18
+ fn: (args: z.infer<S>) => Promise<unknown>;
19
+ }): DynamicStructuredTool;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildTool = buildTool;
4
+ const tools_1 = require("@langchain/core/tools");
5
+ const errors_1 = require("../LoomCycle/helpers/errors");
6
+ /**
7
+ * Build a LangChain `DynamicStructuredTool` with our standard error
8
+ * envelope. Every cluster sub-node uses this helper so the wire surface
9
+ * to the parent AI Agent is uniform.
10
+ *
11
+ * The returned tool's `func` always resolves to a string (LangChain
12
+ * contract). We JSON-stringify structured results; thrown wire errors
13
+ * are caught + redacted + returned as a `{"error": "..."}` string so
14
+ * the agent can read the failure mode without us leaking bearer
15
+ * fragments into the model's context (CLAUDE.md §security.6).
16
+ */
17
+ function buildTool(opts) {
18
+ return new tools_1.DynamicStructuredTool({
19
+ name: opts.name,
20
+ description: opts.description,
21
+ schema: opts.schema,
22
+ func: async (args) => {
23
+ try {
24
+ const result = await opts.fn(args);
25
+ if (typeof result === 'string')
26
+ return result;
27
+ return JSON.stringify(result);
28
+ }
29
+ catch (err) {
30
+ const message = (0, errors_1.redactBearerFragments)(err.message ?? 'unknown loomcycle error');
31
+ return JSON.stringify({ error: message });
32
+ }
33
+ },
34
+ });
35
+ }
36
+ //# sourceMappingURL=clusterTool.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clusterTool.js","sourceRoot":"","sources":["../../../nodes/_shared/clusterTool.ts"],"names":[],"mappings":";;AAeA,8BAqBC;AApCD,iDAA8D;AAE9D,wDAAoE;AAEpE;;;;;;;;;;GAUG;AACH,SAAgB,SAAS,CAAyB,IAKjD;IACA,OAAO,IAAI,6BAAqB,CAAC;QAChC,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,IAAI,EAAE,KAAK,EAAE,IAAgB,EAAmB,EAAE;YACjD,IAAI,CAAC;gBACJ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBACnC,IAAI,OAAO,MAAM,KAAK,QAAQ;oBAAE,OAAO,MAAM,CAAC;gBAC9C,OAAO,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACd,MAAM,OAAO,GAAG,IAAA,8BAAqB,EAAE,GAAa,CAAC,OAAO,IAAI,yBAAyB,CAAC,CAAC;gBAC3F,OAAO,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC;YAC3C,CAAC;QACF,CAAC;KACD,CAAC,CAAC;AACJ,CAAC"}