@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.
- package/LICENSE +201 -0
- package/README.md +190 -0
- package/dist/credentials/LoomCycleApi.credentials.d.ts +21 -0
- package/dist/credentials/LoomCycleApi.credentials.js +81 -0
- package/dist/credentials/LoomCycleApi.credentials.js.map +1 -0
- package/dist/nodes/LoomCycle/LoomCycle.node.d.ts +22 -0
- package/dist/nodes/LoomCycle/LoomCycle.node.js +403 -0
- package/dist/nodes/LoomCycle/LoomCycle.node.js.map +1 -0
- package/dist/nodes/LoomCycle/LoomCycle.node.json +13 -0
- package/dist/nodes/LoomCycle/LoomCycle.svg +13 -0
- package/dist/nodes/LoomCycle/descriptions/agentdef.d.ts +21 -0
- package/dist/nodes/LoomCycle/descriptions/agentdef.js +155 -0
- package/dist/nodes/LoomCycle/descriptions/agentdef.js.map +1 -0
- package/dist/nodes/LoomCycle/descriptions/channels.d.ts +19 -0
- package/dist/nodes/LoomCycle/descriptions/channels.js +164 -0
- package/dist/nodes/LoomCycle/descriptions/channels.js.map +1 -0
- package/dist/nodes/LoomCycle/descriptions/index.d.ts +6 -0
- package/dist/nodes/LoomCycle/descriptions/index.js +16 -0
- package/dist/nodes/LoomCycle/descriptions/index.js.map +1 -0
- package/dist/nodes/LoomCycle/descriptions/mcpserverdef.d.ts +29 -0
- package/dist/nodes/LoomCycle/descriptions/mcpserverdef.js +241 -0
- package/dist/nodes/LoomCycle/descriptions/mcpserverdef.js.map +1 -0
- package/dist/nodes/LoomCycle/descriptions/memory.d.ts +20 -0
- package/dist/nodes/LoomCycle/descriptions/memory.js +119 -0
- package/dist/nodes/LoomCycle/descriptions/memory.js.map +1 -0
- package/dist/nodes/LoomCycle/descriptions/runs.d.ts +17 -0
- package/dist/nodes/LoomCycle/descriptions/runs.js +226 -0
- package/dist/nodes/LoomCycle/descriptions/runs.js.map +1 -0
- package/dist/nodes/LoomCycle/descriptions/skilldef.d.ts +10 -0
- package/dist/nodes/LoomCycle/descriptions/skilldef.js +144 -0
- package/dist/nodes/LoomCycle/descriptions/skilldef.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/capability.d.ts +42 -0
- package/dist/nodes/LoomCycle/helpers/capability.js +54 -0
- package/dist/nodes/LoomCycle/helpers/capability.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/client.d.ts +15 -0
- package/dist/nodes/LoomCycle/helpers/client.js +30 -0
- package/dist/nodes/LoomCycle/helpers/client.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/envVarHints.d.ts +30 -0
- package/dist/nodes/LoomCycle/helpers/envVarHints.js +67 -0
- package/dist/nodes/LoomCycle/helpers/envVarHints.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/errors.d.ts +23 -0
- package/dist/nodes/LoomCycle/helpers/errors.js +189 -0
- package/dist/nodes/LoomCycle/helpers/errors.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/loadOptions.d.ts +24 -0
- package/dist/nodes/LoomCycle/helpers/loadOptions.js +89 -0
- package/dist/nodes/LoomCycle/helpers/loadOptions.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/segments.d.ts +13 -0
- package/dist/nodes/LoomCycle/helpers/segments.js +31 -0
- package/dist/nodes/LoomCycle/helpers/segments.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/staticData.d.ts +5 -0
- package/dist/nodes/LoomCycle/helpers/staticData.js +31 -0
- package/dist/nodes/LoomCycle/helpers/staticData.js.map +1 -0
- package/dist/nodes/LoomCycle/helpers/streaming.d.ts +31 -0
- package/dist/nodes/LoomCycle/helpers/streaming.js +48 -0
- package/dist/nodes/LoomCycle/helpers/streaming.js.map +1 -0
- package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.d.ts +24 -0
- package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.js +162 -0
- package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.js.map +1 -0
- package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.node.json +13 -0
- package/dist/nodes/LoomCycleChannelMessage/LoomCycleChannelMessage.svg +9 -0
- package/dist/nodes/LoomCycleChannelMessage/helpers/subscribe.d.ts +20 -0
- package/dist/nodes/LoomCycleChannelMessage/helpers/subscribe.js +106 -0
- package/dist/nodes/LoomCycleChannelMessage/helpers/subscribe.js.map +1 -0
- package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.d.ts +5 -0
- package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.js +114 -0
- package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.js.map +1 -0
- package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.node.json +13 -0
- package/dist/nodes/LoomCycleChannelTool/LoomCycleChannelTool.svg +13 -0
- package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.d.ts +5 -0
- package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.js +259 -0
- package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.js.map +1 -0
- package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.node.json +13 -0
- package/dist/nodes/LoomCycleMcpServerTool/LoomCycleMcpServerTool.svg +14 -0
- package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.d.ts +5 -0
- package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.js +108 -0
- package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.js.map +1 -0
- package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.node.json +13 -0
- package/dist/nodes/LoomCycleMemoryTool/LoomCycleMemoryTool.svg +11 -0
- package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.d.ts +18 -0
- package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.js +188 -0
- package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.js.map +1 -0
- package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.json +13 -0
- package/dist/nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.svg +10 -0
- package/dist/nodes/LoomCycleRunCompleted/helpers/poll.d.ts +12 -0
- package/dist/nodes/LoomCycleRunCompleted/helpers/poll.js +69 -0
- package/dist/nodes/LoomCycleRunCompleted/helpers/poll.js.map +1 -0
- package/dist/nodes/LoomCycleRunCompleted/helpers/sse.d.ts +29 -0
- package/dist/nodes/LoomCycleRunCompleted/helpers/sse.js +61 -0
- package/dist/nodes/LoomCycleRunCompleted/helpers/sse.js.map +1 -0
- package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.d.ts +5 -0
- package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.js +131 -0
- package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.js.map +1 -0
- package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.node.json +13 -0
- package/dist/nodes/LoomCycleSubAgentTool/LoomCycleSubAgentTool.svg +12 -0
- package/dist/nodes/_shared/clusterTool.d.ts +19 -0
- package/dist/nodes/_shared/clusterTool.js +36 -0
- package/dist/nodes/_shared/clusterTool.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoomCycleRunCompleted.node.js","sourceRoot":"","sources":["../../../nodes/LoomCycleRunCompleted/LoomCycleRunCompleted.node.ts"],"names":[],"mappings":";;;AAQA,wDAA8E;AAC9E,wDAAiE;AACjE,uCAA2C;AAC3C,yCAAuD;AAEvD;;;;;;;;;;;;GAYG;AACH,MAAa,qBAAqB;IAAlC;QACC,gBAAW,GAAyB;YACnC,WAAW,EAAE,0BAA0B;YACvC,IAAI,EAAE,uBAAuB;YAC7B,IAAI,EAAE,gCAAgC;YACtC,KAAK,EAAE,CAAC,SAAS,CAAC;YAClB,OAAO,EAAE,CAAC;YACV,WAAW,EAAE,wFAAwF;YACrG,QAAQ,EAAE,EAAE,IAAI,EAAE,0BAA0B,EAAE;YAC9C,2FAA2F;YAC3F,MAAM,EAAE,EAAE;YACV,OAAO,EAAE,CAAC,MAAM,CAAC;YACjB,WAAW,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YACvD,UAAU,EAAE;gBACX;oBACC,WAAW,EAAE,SAAS;oBACtB,IAAI,EAAE,QAAQ;oBACd,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,EAAE;oBACX,WAAW,EAAE,kEAAkE;iBAC/E;gBACD;oBACC,WAAW,EAAE,UAAU;oBACvB,IAAI,EAAE,UAAU;oBAChB,IAAI,EAAE,cAAc;oBACpB,OAAO,EAAE,CAAC,WAAW,CAAC;oBACtB,OAAO,EAAE;wBACR,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE;wBACzC,EAAE,IAAI,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE;wBACzC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE;qBACnC;oBACD,WAAW,EAAE,2CAA2C;iBACxD;gBACD;oBACC,WAAW,EAAE,WAAW;oBACxB,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE;wBACR;4BACC,IAAI,EAAE,YAAY;4BAClB,KAAK,EAAE,KAAK;4BACZ,WAAW,EAAE,2EAA2E;yBACxF;wBACD;4BACC,IAAI,EAAE,SAAS;4BACf,KAAK,EAAE,MAAM;4BACb,WAAW,EAAE,6DAA6D;yBAC1E;qBACD;iBACD;gBACD;oBACC,WAAW,EAAE,yBAAyB;oBACtC,IAAI,EAAE,aAAa;oBACnB,IAAI,EAAE,QAAQ;oBACd,OAAO,EAAE,EAAE;oBACX,WAAW,EAAE,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;oBAC5C,cAAc,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE;oBAC5C,WAAW,EAAE,oDAAoD;iBACjE;gBACD;oBACC,WAAW,EAAE,mBAAmB;oBAChC,IAAI,EAAE,kBAAkB;oBACxB,IAAI,EAAE,YAAY;oBAClB,WAAW,EAAE,WAAW;oBACxB,OAAO,EAAE,EAAE;oBACX,OAAO,EAAE;wBACR;4BACC,WAAW,EAAE,YAAY;4BACzB,IAAI,EAAE,OAAO;4BACb,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,EAAE;4BACX,WAAW,EAAE,yDAAyD;yBACtE;wBACD;4BACC,WAAW,EAAE,iBAAiB;4BAC9B,IAAI,EAAE,eAAe;4BACrB,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,EAAE;4BACX,WAAW,EAAE,kDAAkD;yBAC/D;wBACD;4BACC,WAAW,EAAE,kCAAkC;4BAC/C,IAAI,EAAE,WAAW;4BACjB,IAAI,EAAE,SAAS;4BACf,OAAO,EAAE,KAAK;4BACd,WAAW,EAAE,yGAAyG;yBACtH;wBACD;4BACC,WAAW,EAAE,wBAAwB;4BACrC,IAAI,EAAE,oBAAoB;4BAC1B,IAAI,EAAE,QAAQ;4BACd,OAAO,EAAE,IAAI;4BACb,WAAW,EAAE,EAAE,QAAQ,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE;4BAC/C,WAAW,EAAE,kFAAkF;yBAC/F;qBACD;iBACD;aACD;SACD,CAAC;IAyEH,CAAC;IAvEA,KAAK,CAAC,OAAO;QACZ,MAAM,WAAW,GAAI,IAAI,CAAC,gBAAgB,CAAC,QAAQ,EAAE,EAAE,CAAY,IAAI,EAAE,CAAC;QAC1E,MAAM,QAAQ,GAAI,IAAI,CAAC,gBAAgB,CAAC,UAAU,EAAE,CAAC,WAAW,CAAC,CAAc,IAAI,CAAC,WAAW,CAAC,CAAC;QACjG,MAAM,IAAI,GAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAY,IAAI,KAAK,CAAC;QACvE,MAAM,WAAW,GAAI,IAAI,CAAC,gBAAgB,CAAC,aAAa,EAAE,EAAE,CAAY,IAAI,EAAE,CAAC;QAC/E,MAAM,gBAAgB,GAAI,IAAI,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,EAAE,CAA6B,IAAI,EAAE,CAAC;QAE1G,MAAM,MAAM,GAAG,WAAW,IAAI,CAAC,MAAM,IAAA,6BAAoB,EAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC3E,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAA,2BAAkB,EACvB,IAAI,KAAK,CAAC,yEAAyE,CAAC,EACpF,IAAI,CAAC,OAAO,EAAE,CACd,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAA,kBAAS,EAAC,IAAI,CAAC,CAAC;QACrC,MAAM,EAAE,GAAG,IAAI,eAAe,EAAE,CAAC;QAEjC,MAAM,KAAK,GAAI,gBAAgB,CAAC,KAAgB,IAAI,SAAS,CAAC;QAC9D,MAAM,aAAa,GAAI,gBAAgB,CAAC,aAAwB,IAAI,SAAS,CAAC;QAC9E,MAAM,SAAS,GAAI,gBAAgB,CAAC,SAAqB,IAAI,KAAK,CAAC;QACnE,MAAM,kBAAkB,GAAI,gBAAgB,CAAC,kBAA6B,IAAI,IAAI,CAAC;QAEnF,gEAAgE;QAChE,uDAAuD;QACvD,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACrB,KAAK,kBAAW,CAAC,IAAI,CAAC,IAAI,EAAE;gBAC3B,MAAM;gBACN,MAAM;gBACN,QAAQ,EAAE,QAAyB;gBACnC,aAAa;gBACb,UAAU,EAAE,WAAW,GAAG,IAAI;gBAC9B,MAAM,EAAE,EAAE,CAAC,MAAM;aACjB,CAAC,CAAC;QACJ,CAAC;aAAM,CAAC;YACP,KAAK,gBAAU,CAAC,IAAI,CAAC,IAAI,EAAE;gBAC1B,MAAM;gBACN,MAAM;gBACN,QAAQ;gBACR,aAAa;gBACb,KAAK;gBACL,KAAK,EAAE,SAAS;gBAChB,SAAS;gBACT,MAAM,EAAE,EAAE,CAAC,MAAM;gBACjB,kBAAkB;aAClB,CAAC,CAAC;QACJ,CAAC;QAED,kEAAkE;QAClE,kEAAkE;QAClE,qBAAqB;QACrB,KAAK,UAAU,qBAAqB;YACnC,MAAM,SAAS,GAAG,IAAI,eAAe,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,MAAM,CAAC;YAC3B,MAAM,eAAQ,CAAC,IAAI,CAAC,IAAI,EAAE;gBACzB,MAAM;gBACN,MAAM,EAAE,WAAW;gBACnB,QAAQ,EAAE,QAAyB;gBACnC,aAAa;gBACb,UAAU,EAAE,CAAC;gBACb,MAAM,EAAE,SAAS,CAAC,MAAM;aACxB,CAAC,CAAC;QACJ,CAAC;QAED,OAAO;YACN,aAAa,EAAE,KAAK,IAAI,EAAE;gBACzB,EAAE,CAAC,KAAK,EAAE,CAAC;YACZ,CAAC;YACD,qBAAqB,EAAE,qBAAqB,CAAC,IAAI,CAAC,IAAI,CAAC;SACvD,CAAC;IACH,CAAC;CACD;AA5KD,sDA4KC"}
|
|
@@ -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"}
|