@jiggai/recipes 0.4.26 → 0.4.27

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.
@@ -2,7 +2,7 @@
2
2
  "id": "recipes",
3
3
  "name": "Recipes",
4
4
  "description": "Markdown recipes that scaffold agents and teams (workspace-local).",
5
- "version": "0.4.26",
5
+ "version": "0.4.27",
6
6
  "configSchema": {
7
7
  "type": "object",
8
8
  "additionalProperties": false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jiggai/recipes",
3
- "version": "0.4.26",
3
+ "version": "0.4.27",
4
4
  "description": "ClawRecipes plugin for OpenClaw (markdown recipes -> scaffold agents/teams)",
5
5
  "main": "index.ts",
6
6
  "type": "commonjs",
@@ -19,15 +19,21 @@ import {
19
19
  sanitizeDraftOnlyText, templateReplace,
20
20
  } from './workflow-utils';
21
21
 
22
+ // Max depth for event-driven chaining to prevent runaway recursion.
23
+ const maxChainDepth = 20;
24
+
22
25
  // eslint-disable-next-line complexity, max-lines-per-function
23
26
  export async function runWorkflowWorkerTick(api: OpenClawPluginApi, opts: {
24
27
  teamId: string;
25
28
  agentId: string;
26
29
  limit?: number;
27
30
  workerId?: string;
28
- }) {
31
+ /** Disable event-driven chaining (used in tests to control execution order). */
32
+ noChain?: boolean;
33
+ }, chainDepth = 0) {
29
34
  const teamId = String(opts.teamId);
30
35
  const agentId = String(opts.agentId);
36
+ const noChain = !!opts.noChain;
31
37
  if (!teamId) throw new Error('--team-id is required');
32
38
  if (!agentId) throw new Error('--agent-id is required');
33
39
 
@@ -578,6 +584,12 @@ export async function runWorkflowWorkerTick(api: OpenClawPluginApi, opts: {
578
584
  events: [...cur.events, { ts: new Date().toISOString(), type: 'node.enqueued', nodeId: nextNode.id, agentId: approvalAgentId }],
579
585
  }));
580
586
 
587
+ // Event-driven chaining: immediately kick the next agent's worker
588
+ if (!noChain && approvalAgentId !== agentId && chainDepth < maxChainDepth) {
589
+ void runWorkflowWorkerTick(api, { teamId, agentId: approvalAgentId, limit: 1, workerId: `${workerId}:chain` }, chainDepth + 1)
590
+ .catch(() => { /* best-effort — cron workers are the safety net */ });
591
+ }
592
+
581
593
  results.push({ taskId: task.id, runId: task.runId, nodeId: task.nodeId, status: 'ok' });
582
594
  continue;
583
595
  }
@@ -600,6 +612,12 @@ export async function runWorkflowWorkerTick(api: OpenClawPluginApi, opts: {
600
612
  events: [...cur.events, { ts: new Date().toISOString(), type: 'node.enqueued', nodeId: nextNode.id, agentId: nextAgentId }],
601
613
  }));
602
614
 
615
+ // Event-driven chaining: immediately kick the next agent's worker
616
+ if (!noChain && nextAgentId !== agentId && chainDepth < maxChainDepth) {
617
+ void runWorkflowWorkerTick(api, { teamId, agentId: nextAgentId, limit: 1, workerId: `${workerId}:chain` }, chainDepth + 1)
618
+ .catch(() => { /* best-effort — cron workers are the safety net */ });
619
+ }
620
+
603
621
  results.push({ taskId: task.id, runId: task.runId, nodeId: task.nodeId, status: 'ok' });
604
622
  } finally {
605
623
  if (lockHeld) {