@enfyra/mcp-server 0.3.19 → 0.3.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/lib/mcp-example-flows.js +13 -25
- package/dist/lib/mcp-example-flows.js.map +1 -1
- package/dist/lib/method-tools.js +32 -26
- package/dist/lib/method-tools.js.map +1 -1
- package/dist/lib/mutation-guards.d.ts +6 -0
- package/dist/lib/mutation-guards.js +40 -0
- package/dist/lib/mutation-guards.js.map +1 -1
- package/dist/lib/platform-data-operations.js +0 -1
- package/dist/lib/platform-data-operations.js.map +1 -1
- package/dist/lib/platform-flow-operations.d.ts +4 -387
- package/dist/lib/platform-flow-operations.js +14 -105
- package/dist/lib/platform-flow-operations.js.map +1 -1
- package/dist/lib/platform-flow-tools.js +12 -119
- package/dist/lib/platform-flow-tools.js.map +1 -1
- package/dist/lib/platform-operation-tools.d.ts +1 -1
- package/dist/lib/platform-operation-tools.js +1 -1
- package/dist/lib/platform-operation-tools.js.map +1 -1
- package/dist/lib/platform-operation-types.d.ts +0 -1
- package/dist/lib/required-knowledge.js +2 -2
- package/dist/lib/required-knowledge.js.map +1 -1
- package/dist/lib/workflow-definitions.js +4 -4
- package/dist/lib/workflow-definitions.js.map +1 -1
- package/package.json +1 -1
|
@@ -310,13 +310,12 @@ export declare function deleteFlowStep(apiUrl: any, { flowName, flowId, stepId,
|
|
|
310
310
|
};
|
|
311
311
|
action: string;
|
|
312
312
|
}>;
|
|
313
|
-
export declare function ensureFlowStep(apiUrl: any, { flowName, flowId, key, type, order,
|
|
313
|
+
export declare function ensureFlowStep(apiUrl: any, { flowName, flowId, key, type, order, sourceCode, sourceFile, sourceResourceUri, scriptLanguage, timeout, isEnabled, globalRulesAckKey, knowledgeAckKey, }: {
|
|
314
314
|
flowName: any;
|
|
315
315
|
flowId: any;
|
|
316
316
|
key: any;
|
|
317
317
|
type: any;
|
|
318
318
|
order: any;
|
|
319
|
-
config: any;
|
|
320
319
|
sourceCode: any;
|
|
321
320
|
sourceFile: any;
|
|
322
321
|
sourceResourceUri: any;
|
|
@@ -362,397 +361,19 @@ export declare function ensureFlowStep(apiUrl: any, { flowName, flowId, key, typ
|
|
|
362
361
|
reason: string;
|
|
363
362
|
};
|
|
364
363
|
}>;
|
|
365
|
-
export declare
|
|
366
|
-
|
|
367
|
-
type: string;
|
|
368
|
-
when: string;
|
|
369
|
-
config: {
|
|
370
|
-
table: string;
|
|
371
|
-
filter: {};
|
|
372
|
-
fields: string;
|
|
373
|
-
limit: number;
|
|
374
|
-
sort: string;
|
|
375
|
-
data?: undefined;
|
|
376
|
-
id?: undefined;
|
|
377
|
-
url?: undefined;
|
|
378
|
-
method?: undefined;
|
|
379
|
-
headers?: undefined;
|
|
380
|
-
body?: undefined;
|
|
381
|
-
timeout?: undefined;
|
|
382
|
-
ms?: undefined;
|
|
383
|
-
flowName?: undefined;
|
|
384
|
-
payload?: undefined;
|
|
385
|
-
message?: undefined;
|
|
386
|
-
};
|
|
387
|
-
sourceCode?: undefined;
|
|
388
|
-
} | {
|
|
389
|
-
tool: string;
|
|
390
|
-
type: string;
|
|
391
|
-
when: string;
|
|
392
|
-
config: {
|
|
393
|
-
table: string;
|
|
394
|
-
data: {
|
|
395
|
-
field: string;
|
|
396
|
-
};
|
|
397
|
-
filter?: undefined;
|
|
398
|
-
fields?: undefined;
|
|
399
|
-
limit?: undefined;
|
|
400
|
-
sort?: undefined;
|
|
401
|
-
id?: undefined;
|
|
402
|
-
url?: undefined;
|
|
403
|
-
method?: undefined;
|
|
404
|
-
headers?: undefined;
|
|
405
|
-
body?: undefined;
|
|
406
|
-
timeout?: undefined;
|
|
407
|
-
ms?: undefined;
|
|
408
|
-
flowName?: undefined;
|
|
409
|
-
payload?: undefined;
|
|
410
|
-
message?: undefined;
|
|
411
|
-
};
|
|
412
|
-
sourceCode?: undefined;
|
|
413
|
-
} | {
|
|
414
|
-
tool: string;
|
|
415
|
-
type: string;
|
|
416
|
-
when: string;
|
|
417
|
-
config: {
|
|
418
|
-
table: string;
|
|
419
|
-
id: string;
|
|
420
|
-
data: {
|
|
421
|
-
field: string;
|
|
422
|
-
};
|
|
423
|
-
filter?: undefined;
|
|
424
|
-
fields?: undefined;
|
|
425
|
-
limit?: undefined;
|
|
426
|
-
sort?: undefined;
|
|
427
|
-
url?: undefined;
|
|
428
|
-
method?: undefined;
|
|
429
|
-
headers?: undefined;
|
|
430
|
-
body?: undefined;
|
|
431
|
-
timeout?: undefined;
|
|
432
|
-
ms?: undefined;
|
|
433
|
-
flowName?: undefined;
|
|
434
|
-
payload?: undefined;
|
|
435
|
-
message?: undefined;
|
|
436
|
-
};
|
|
437
|
-
sourceCode?: undefined;
|
|
438
|
-
} | {
|
|
439
|
-
tool: string;
|
|
440
|
-
type: string;
|
|
441
|
-
when: string;
|
|
442
|
-
config: {
|
|
443
|
-
table: string;
|
|
444
|
-
id: string;
|
|
445
|
-
filter?: undefined;
|
|
446
|
-
fields?: undefined;
|
|
447
|
-
limit?: undefined;
|
|
448
|
-
sort?: undefined;
|
|
449
|
-
data?: undefined;
|
|
450
|
-
url?: undefined;
|
|
451
|
-
method?: undefined;
|
|
452
|
-
headers?: undefined;
|
|
453
|
-
body?: undefined;
|
|
454
|
-
timeout?: undefined;
|
|
455
|
-
ms?: undefined;
|
|
456
|
-
flowName?: undefined;
|
|
457
|
-
payload?: undefined;
|
|
458
|
-
message?: undefined;
|
|
459
|
-
};
|
|
460
|
-
sourceCode?: undefined;
|
|
461
|
-
} | {
|
|
462
|
-
tool: string;
|
|
463
|
-
type: string;
|
|
464
|
-
when: string;
|
|
465
|
-
config: {
|
|
466
|
-
url: string;
|
|
467
|
-
method: string;
|
|
468
|
-
headers: {};
|
|
469
|
-
body: {};
|
|
470
|
-
timeout: number;
|
|
471
|
-
table?: undefined;
|
|
472
|
-
filter?: undefined;
|
|
473
|
-
fields?: undefined;
|
|
474
|
-
limit?: undefined;
|
|
475
|
-
sort?: undefined;
|
|
476
|
-
data?: undefined;
|
|
477
|
-
id?: undefined;
|
|
478
|
-
ms?: undefined;
|
|
479
|
-
flowName?: undefined;
|
|
480
|
-
payload?: undefined;
|
|
481
|
-
message?: undefined;
|
|
482
|
-
};
|
|
483
|
-
sourceCode?: undefined;
|
|
484
|
-
} | {
|
|
364
|
+
export declare function assertFlowStepTypeIsSupported(type: any): void;
|
|
365
|
+
export declare const FLOW_STEP_TOOL_GUIDANCE: {
|
|
485
366
|
tool: string;
|
|
486
367
|
type: string;
|
|
487
368
|
when: string;
|
|
488
369
|
sourceCode: string;
|
|
489
|
-
|
|
490
|
-
} | {
|
|
491
|
-
tool: string;
|
|
492
|
-
type: string;
|
|
493
|
-
when: string;
|
|
494
|
-
config: {
|
|
495
|
-
ms: number;
|
|
496
|
-
table?: undefined;
|
|
497
|
-
filter?: undefined;
|
|
498
|
-
fields?: undefined;
|
|
499
|
-
limit?: undefined;
|
|
500
|
-
sort?: undefined;
|
|
501
|
-
data?: undefined;
|
|
502
|
-
id?: undefined;
|
|
503
|
-
url?: undefined;
|
|
504
|
-
method?: undefined;
|
|
505
|
-
headers?: undefined;
|
|
506
|
-
body?: undefined;
|
|
507
|
-
timeout?: undefined;
|
|
508
|
-
flowName?: undefined;
|
|
509
|
-
payload?: undefined;
|
|
510
|
-
message?: undefined;
|
|
511
|
-
};
|
|
512
|
-
sourceCode?: undefined;
|
|
513
|
-
} | {
|
|
514
|
-
tool: string;
|
|
515
|
-
type: string;
|
|
516
|
-
when: string;
|
|
517
|
-
config: {
|
|
518
|
-
flowName: string;
|
|
519
|
-
payload: {};
|
|
520
|
-
table?: undefined;
|
|
521
|
-
filter?: undefined;
|
|
522
|
-
fields?: undefined;
|
|
523
|
-
limit?: undefined;
|
|
524
|
-
sort?: undefined;
|
|
525
|
-
data?: undefined;
|
|
526
|
-
id?: undefined;
|
|
527
|
-
url?: undefined;
|
|
528
|
-
method?: undefined;
|
|
529
|
-
headers?: undefined;
|
|
530
|
-
body?: undefined;
|
|
531
|
-
timeout?: undefined;
|
|
532
|
-
ms?: undefined;
|
|
533
|
-
message?: undefined;
|
|
534
|
-
};
|
|
535
|
-
sourceCode?: undefined;
|
|
536
|
-
} | {
|
|
537
|
-
tool: string;
|
|
538
|
-
type: string;
|
|
539
|
-
when: string;
|
|
540
|
-
config: {
|
|
541
|
-
message: string;
|
|
542
|
-
table?: undefined;
|
|
543
|
-
filter?: undefined;
|
|
544
|
-
fields?: undefined;
|
|
545
|
-
limit?: undefined;
|
|
546
|
-
sort?: undefined;
|
|
547
|
-
data?: undefined;
|
|
548
|
-
id?: undefined;
|
|
549
|
-
url?: undefined;
|
|
550
|
-
method?: undefined;
|
|
551
|
-
headers?: undefined;
|
|
552
|
-
body?: undefined;
|
|
553
|
-
timeout?: undefined;
|
|
554
|
-
ms?: undefined;
|
|
555
|
-
flowName?: undefined;
|
|
556
|
-
payload?: undefined;
|
|
557
|
-
};
|
|
558
|
-
sourceCode?: undefined;
|
|
559
|
-
})[];
|
|
370
|
+
}[];
|
|
560
371
|
export declare function chooseFlowStepTool(intent: any): {
|
|
561
|
-
tool: string;
|
|
562
|
-
type: string;
|
|
563
|
-
when: string;
|
|
564
|
-
config: {
|
|
565
|
-
table: string;
|
|
566
|
-
filter: {};
|
|
567
|
-
fields: string;
|
|
568
|
-
limit: number;
|
|
569
|
-
sort: string;
|
|
570
|
-
data?: undefined;
|
|
571
|
-
id?: undefined;
|
|
572
|
-
url?: undefined;
|
|
573
|
-
method?: undefined;
|
|
574
|
-
headers?: undefined;
|
|
575
|
-
body?: undefined;
|
|
576
|
-
timeout?: undefined;
|
|
577
|
-
ms?: undefined;
|
|
578
|
-
flowName?: undefined;
|
|
579
|
-
payload?: undefined;
|
|
580
|
-
message?: undefined;
|
|
581
|
-
};
|
|
582
|
-
sourceCode?: undefined;
|
|
583
|
-
} | {
|
|
584
|
-
tool: string;
|
|
585
|
-
type: string;
|
|
586
|
-
when: string;
|
|
587
|
-
config: {
|
|
588
|
-
table: string;
|
|
589
|
-
data: {
|
|
590
|
-
field: string;
|
|
591
|
-
};
|
|
592
|
-
filter?: undefined;
|
|
593
|
-
fields?: undefined;
|
|
594
|
-
limit?: undefined;
|
|
595
|
-
sort?: undefined;
|
|
596
|
-
id?: undefined;
|
|
597
|
-
url?: undefined;
|
|
598
|
-
method?: undefined;
|
|
599
|
-
headers?: undefined;
|
|
600
|
-
body?: undefined;
|
|
601
|
-
timeout?: undefined;
|
|
602
|
-
ms?: undefined;
|
|
603
|
-
flowName?: undefined;
|
|
604
|
-
payload?: undefined;
|
|
605
|
-
message?: undefined;
|
|
606
|
-
};
|
|
607
|
-
sourceCode?: undefined;
|
|
608
|
-
} | {
|
|
609
|
-
tool: string;
|
|
610
|
-
type: string;
|
|
611
|
-
when: string;
|
|
612
|
-
config: {
|
|
613
|
-
table: string;
|
|
614
|
-
id: string;
|
|
615
|
-
data: {
|
|
616
|
-
field: string;
|
|
617
|
-
};
|
|
618
|
-
filter?: undefined;
|
|
619
|
-
fields?: undefined;
|
|
620
|
-
limit?: undefined;
|
|
621
|
-
sort?: undefined;
|
|
622
|
-
url?: undefined;
|
|
623
|
-
method?: undefined;
|
|
624
|
-
headers?: undefined;
|
|
625
|
-
body?: undefined;
|
|
626
|
-
timeout?: undefined;
|
|
627
|
-
ms?: undefined;
|
|
628
|
-
flowName?: undefined;
|
|
629
|
-
payload?: undefined;
|
|
630
|
-
message?: undefined;
|
|
631
|
-
};
|
|
632
|
-
sourceCode?: undefined;
|
|
633
|
-
} | {
|
|
634
|
-
tool: string;
|
|
635
|
-
type: string;
|
|
636
|
-
when: string;
|
|
637
|
-
config: {
|
|
638
|
-
table: string;
|
|
639
|
-
id: string;
|
|
640
|
-
filter?: undefined;
|
|
641
|
-
fields?: undefined;
|
|
642
|
-
limit?: undefined;
|
|
643
|
-
sort?: undefined;
|
|
644
|
-
data?: undefined;
|
|
645
|
-
url?: undefined;
|
|
646
|
-
method?: undefined;
|
|
647
|
-
headers?: undefined;
|
|
648
|
-
body?: undefined;
|
|
649
|
-
timeout?: undefined;
|
|
650
|
-
ms?: undefined;
|
|
651
|
-
flowName?: undefined;
|
|
652
|
-
payload?: undefined;
|
|
653
|
-
message?: undefined;
|
|
654
|
-
};
|
|
655
|
-
sourceCode?: undefined;
|
|
656
|
-
} | {
|
|
657
|
-
tool: string;
|
|
658
|
-
type: string;
|
|
659
|
-
when: string;
|
|
660
|
-
config: {
|
|
661
|
-
url: string;
|
|
662
|
-
method: string;
|
|
663
|
-
headers: {};
|
|
664
|
-
body: {};
|
|
665
|
-
timeout: number;
|
|
666
|
-
table?: undefined;
|
|
667
|
-
filter?: undefined;
|
|
668
|
-
fields?: undefined;
|
|
669
|
-
limit?: undefined;
|
|
670
|
-
sort?: undefined;
|
|
671
|
-
data?: undefined;
|
|
672
|
-
id?: undefined;
|
|
673
|
-
ms?: undefined;
|
|
674
|
-
flowName?: undefined;
|
|
675
|
-
payload?: undefined;
|
|
676
|
-
message?: undefined;
|
|
677
|
-
};
|
|
678
|
-
sourceCode?: undefined;
|
|
679
|
-
} | {
|
|
680
372
|
tool: string;
|
|
681
373
|
type: string;
|
|
682
374
|
when: string;
|
|
683
375
|
sourceCode: string;
|
|
684
|
-
config?: undefined;
|
|
685
|
-
} | {
|
|
686
|
-
tool: string;
|
|
687
|
-
type: string;
|
|
688
|
-
when: string;
|
|
689
|
-
config: {
|
|
690
|
-
ms: number;
|
|
691
|
-
table?: undefined;
|
|
692
|
-
filter?: undefined;
|
|
693
|
-
fields?: undefined;
|
|
694
|
-
limit?: undefined;
|
|
695
|
-
sort?: undefined;
|
|
696
|
-
data?: undefined;
|
|
697
|
-
id?: undefined;
|
|
698
|
-
url?: undefined;
|
|
699
|
-
method?: undefined;
|
|
700
|
-
headers?: undefined;
|
|
701
|
-
body?: undefined;
|
|
702
|
-
timeout?: undefined;
|
|
703
|
-
flowName?: undefined;
|
|
704
|
-
payload?: undefined;
|
|
705
|
-
message?: undefined;
|
|
706
|
-
};
|
|
707
|
-
sourceCode?: undefined;
|
|
708
|
-
} | {
|
|
709
|
-
tool: string;
|
|
710
|
-
type: string;
|
|
711
|
-
when: string;
|
|
712
|
-
config: {
|
|
713
|
-
flowName: string;
|
|
714
|
-
payload: {};
|
|
715
|
-
table?: undefined;
|
|
716
|
-
filter?: undefined;
|
|
717
|
-
fields?: undefined;
|
|
718
|
-
limit?: undefined;
|
|
719
|
-
sort?: undefined;
|
|
720
|
-
data?: undefined;
|
|
721
|
-
id?: undefined;
|
|
722
|
-
url?: undefined;
|
|
723
|
-
method?: undefined;
|
|
724
|
-
headers?: undefined;
|
|
725
|
-
body?: undefined;
|
|
726
|
-
timeout?: undefined;
|
|
727
|
-
ms?: undefined;
|
|
728
|
-
message?: undefined;
|
|
729
|
-
};
|
|
730
|
-
sourceCode?: undefined;
|
|
731
|
-
} | {
|
|
732
|
-
tool: string;
|
|
733
|
-
type: string;
|
|
734
|
-
when: string;
|
|
735
|
-
config: {
|
|
736
|
-
message: string;
|
|
737
|
-
table?: undefined;
|
|
738
|
-
filter?: undefined;
|
|
739
|
-
fields?: undefined;
|
|
740
|
-
limit?: undefined;
|
|
741
|
-
sort?: undefined;
|
|
742
|
-
data?: undefined;
|
|
743
|
-
id?: undefined;
|
|
744
|
-
url?: undefined;
|
|
745
|
-
method?: undefined;
|
|
746
|
-
headers?: undefined;
|
|
747
|
-
body?: undefined;
|
|
748
|
-
timeout?: undefined;
|
|
749
|
-
ms?: undefined;
|
|
750
|
-
flowName?: undefined;
|
|
751
|
-
payload?: undefined;
|
|
752
|
-
};
|
|
753
|
-
sourceCode?: undefined;
|
|
754
376
|
};
|
|
755
|
-
export declare function assertFixedFlowStepConfigIsStatic(type: any, config: any, index?: number): void;
|
|
756
377
|
export declare function planFlowSteps(steps: any): {
|
|
757
378
|
order: number;
|
|
758
379
|
key: string;
|
|
@@ -760,9 +381,7 @@ export declare function planFlowSteps(steps: any): {
|
|
|
760
381
|
tool: any;
|
|
761
382
|
type: any;
|
|
762
383
|
suggestedInput: {
|
|
763
|
-
condition?: any;
|
|
764
384
|
sourceCode?: any;
|
|
765
|
-
config?: any;
|
|
766
385
|
key: string;
|
|
767
386
|
name: any;
|
|
768
387
|
order: number;
|
|
@@ -782,7 +401,6 @@ export declare function runFlowWorkflow(apiUrl: any, opts: any): Promise<{
|
|
|
782
401
|
intent: string;
|
|
783
402
|
type: string;
|
|
784
403
|
order: any;
|
|
785
|
-
config: any;
|
|
786
404
|
sourceCode: any;
|
|
787
405
|
sourceFile: any;
|
|
788
406
|
sourceResourceUri: any;
|
|
@@ -827,7 +445,6 @@ export declare function runFlowWorkflow(apiUrl: any, opts: any): Promise<{
|
|
|
827
445
|
intent: string;
|
|
828
446
|
type: string;
|
|
829
447
|
order: any;
|
|
830
|
-
config: any;
|
|
831
448
|
sourceFile: any;
|
|
832
449
|
sourceResourceUri: any;
|
|
833
450
|
scriptLanguage: any;
|
|
@@ -5,6 +5,7 @@ import { getId, } from './platform-route-operations.js';
|
|
|
5
5
|
import { assertDynamicCodeKnowledgeAck, assertDynamicCodeKnowledgeAckIf, assertGlobalRulesAck } from './required-knowledge.js';
|
|
6
6
|
import { materializeSourceInput } from './source-artifacts.js';
|
|
7
7
|
import { executeSequentialBatch } from './sequential-batch.js';
|
|
8
|
+
import { validateConditionStepSource } from './mutation-guards.js';
|
|
8
9
|
export async function ensureFlow(apiUrl, { name, timeout, maxExecutions = 100, isEnabled = true, description, globalRulesAckKey, }) {
|
|
9
10
|
assertGlobalRulesAck(globalRulesAckKey);
|
|
10
11
|
const existing = await findRecord(apiUrl, 'enfyra_flow', { name: { _eq: name } }, 'id,_id,name');
|
|
@@ -339,18 +340,18 @@ export async function deleteFlowStep(apiUrl, { flowName, flowId, stepId, stepKey
|
|
|
339
340
|
reload: naturalPartialReload('Flow step deletion reloads the active flow registry.'),
|
|
340
341
|
};
|
|
341
342
|
}
|
|
342
|
-
export async function ensureFlowStep(apiUrl, { flowName, flowId, key, type, order,
|
|
343
|
+
export async function ensureFlowStep(apiUrl, { flowName, flowId, key, type, order, sourceCode, sourceFile, sourceResourceUri, scriptLanguage, timeout, isEnabled, globalRulesAckKey, knowledgeAckKey, }) {
|
|
343
344
|
assertGlobalRulesAck(globalRulesAckKey);
|
|
344
345
|
if (!flowName && !flowId)
|
|
345
346
|
throw new Error('Provide flowName or flowId.');
|
|
346
347
|
if (flowName && flowId)
|
|
347
348
|
throw new Error('Provide flowName or flowId, not both.');
|
|
349
|
+
assertFlowStepTypeIsSupported(type);
|
|
348
350
|
const flow = flowId
|
|
349
351
|
? await findRecord(apiUrl, 'enfyra_flow', { id: { _eq: flowId } }, 'id,_id,name')
|
|
350
352
|
: await findRecord(apiUrl, 'enfyra_flow', { name: { _eq: flowName } }, 'id,_id,name');
|
|
351
353
|
if (!flow)
|
|
352
354
|
throw new Error(`Flow not found: ${flowId || flowName}`);
|
|
353
|
-
const parsedConfig = parseJsonObjectArg('config', config, {});
|
|
354
355
|
const dynamicType = ['script', 'condition'].includes(type);
|
|
355
356
|
if (dynamicType && sourceCode === undefined && sourceFile === undefined && sourceResourceUri === undefined) {
|
|
356
357
|
throw new Error(`${type} flow steps require sourceCode, sourceFile, or sourceResourceUri.`);
|
|
@@ -366,6 +367,8 @@ export async function ensureFlowStep(apiUrl, { flowName, flowId, key, type, orde
|
|
|
366
367
|
})
|
|
367
368
|
: null;
|
|
368
369
|
const effectiveSourceCode = materialized?.source;
|
|
370
|
+
if (type === 'condition')
|
|
371
|
+
validateConditionStepSource(effectiveSourceCode);
|
|
369
372
|
assertDynamicCodeKnowledgeAckIf(Boolean(effectiveSourceCode), knowledgeAckKey);
|
|
370
373
|
const validation = effectiveSourceCode
|
|
371
374
|
? await validateDynamicScript(apiUrl, effectiveSourceCode, scriptLanguage)
|
|
@@ -378,7 +381,6 @@ export async function ensureFlowStep(apiUrl, { flowName, flowId, key, type, orde
|
|
|
378
381
|
key,
|
|
379
382
|
type,
|
|
380
383
|
order,
|
|
381
|
-
config: parsedConfig,
|
|
382
384
|
sourceCode: effectiveSourceCode,
|
|
383
385
|
scriptLanguage,
|
|
384
386
|
timeout,
|
|
@@ -387,65 +389,23 @@ export async function ensureFlowStep(apiUrl, { flowName, flowId, key, type, orde
|
|
|
387
389
|
const reload = naturalPartialReload('Flow step writes trigger the server partial reload contract; there is no dedicated flow reload endpoint.');
|
|
388
390
|
return { action: 'flow_step_ensured', flow: { id: getId(flow), name: flow.name }, step: { id: operation.id, key, type }, validation, ...(materialized ? { sourceArtifact: materialized.sourceArtifact } : {}), operation, reload };
|
|
389
391
|
}
|
|
392
|
+
const FLOW_STEP_TYPES = new Set(['script', 'condition']);
|
|
393
|
+
export function assertFlowStepTypeIsSupported(type) {
|
|
394
|
+
if (!FLOW_STEP_TYPES.has(String(type))) {
|
|
395
|
+
throw new Error('Flow steps are script-only: type must be script or condition.');
|
|
396
|
+
}
|
|
397
|
+
}
|
|
390
398
|
export const FLOW_STEP_TOOL_GUIDANCE = [
|
|
391
|
-
{
|
|
392
|
-
tool: 'ensure_query_flow_step',
|
|
393
|
-
type: 'query',
|
|
394
|
-
when: 'Read/list records from one table without custom branching or transformation.',
|
|
395
|
-
config: { table: 'table_name', filter: {}, fields: 'id,name', limit: 20, sort: '-createdAt' },
|
|
396
|
-
},
|
|
397
|
-
{
|
|
398
|
-
tool: 'ensure_create_flow_step',
|
|
399
|
-
type: 'create',
|
|
400
|
-
when: 'Create one record from static config only. Fixed step config is not template-transformed; use a script step when data comes from @FLOW_PAYLOAD, @FLOW_LAST, or @FLOW.',
|
|
401
|
-
config: { table: 'table_name', data: { field: 'value' } },
|
|
402
|
-
},
|
|
403
|
-
{
|
|
404
|
-
tool: 'ensure_update_flow_step',
|
|
405
|
-
type: 'update',
|
|
406
|
-
when: 'Update one statically known record. Use a script step when id or data comes from runtime flow values.',
|
|
407
|
-
config: { table: 'table_name', id: '<static-id>', data: { field: 'value' } },
|
|
408
|
-
},
|
|
409
|
-
{
|
|
410
|
-
tool: 'ensure_delete_flow_step',
|
|
411
|
-
type: 'delete',
|
|
412
|
-
when: 'Delete one statically known record. Use a script step when id comes from runtime flow values.',
|
|
413
|
-
config: { table: 'table_name', id: '<static-id>' },
|
|
414
|
-
},
|
|
415
|
-
{
|
|
416
|
-
tool: 'ensure_http_flow_step',
|
|
417
|
-
type: 'http',
|
|
418
|
-
when: 'Call an external HTTP API.',
|
|
419
|
-
config: { url: 'https://example.com/api', method: 'POST', headers: {}, body: {}, timeout: 10000 },
|
|
420
|
-
},
|
|
421
399
|
{
|
|
422
400
|
tool: 'ensure_condition_flow_step',
|
|
423
401
|
type: 'condition',
|
|
424
|
-
when: 'Branch into true/false child steps
|
|
402
|
+
when: 'Branch into true/false child steps. The source must return a real boolean; the server rejects objects, arrays, strings, numbers, null, and undefined.',
|
|
425
403
|
sourceCode: 'return Boolean(@FLOW_PAYLOAD.enabled)',
|
|
426
404
|
},
|
|
427
|
-
{
|
|
428
|
-
tool: 'ensure_sleep_flow_step',
|
|
429
|
-
type: 'sleep',
|
|
430
|
-
when: 'Wait for a short bounded delay.',
|
|
431
|
-
config: { ms: 1000 },
|
|
432
|
-
},
|
|
433
|
-
{
|
|
434
|
-
tool: 'ensure_trigger_flow_step',
|
|
435
|
-
type: 'trigger_flow',
|
|
436
|
-
when: 'Trigger another flow as a child/orchestration step.',
|
|
437
|
-
config: { flowName: 'child-flow', payload: {} },
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
tool: 'ensure_log_flow_step',
|
|
441
|
-
type: 'log',
|
|
442
|
-
when: 'Record a small execution note for diagnostics.',
|
|
443
|
-
config: { message: 'Reached step_name' },
|
|
444
|
-
},
|
|
445
405
|
{
|
|
446
406
|
tool: 'ensure_script_flow_step',
|
|
447
407
|
type: 'script',
|
|
448
|
-
when: '
|
|
408
|
+
when: 'The only executable step kind. Query, create, update, delete, HTTP, delay, child-flow trigger, and logging all run inside one focused script step using @REPOS/#table, @FETCH, @HELPERS.$sleep, @TRIGGER, and @LOGS.',
|
|
449
409
|
sourceCode: 'return { ok: true }',
|
|
450
410
|
},
|
|
451
411
|
];
|
|
@@ -454,54 +414,8 @@ export function chooseFlowStepTool(intent) {
|
|
|
454
414
|
const hasAny = (patterns) => patterns.some((pattern) => pattern.test(text));
|
|
455
415
|
if (hasAny([/\bif\b/, /\belse\b/, /\bbranch\b/, /\bcondition\b/, /\bwhen\b/, /\bcheck\b/, /nếu/, /điều kiện/]))
|
|
456
416
|
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'condition');
|
|
457
|
-
if (hasAny([/\bhttp\b/, /\bapi\b/, /\bwebhook\b/, /\bfetch\b/, /\brequest\b/, /\bpost\b/, /\bget\b/, /\bcall\b/, /gọi api/]))
|
|
458
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'http');
|
|
459
|
-
if (hasAny([/\bsleep\b/, /\bwait\b/, /\bdelay\b/, /\bpause\b/, /chờ/, /đợi/]))
|
|
460
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'sleep');
|
|
461
|
-
if (hasAny([/\btrigger\b/, /\bchild flow\b/, /\banother flow\b/, /\bsubflow\b/, /flow khác/]))
|
|
462
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'trigger_flow');
|
|
463
|
-
if (hasAny([/\bdelete\b/, /\bremove\b/, /\bdestroy\b/, /xóa/, /xoá/]))
|
|
464
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'delete');
|
|
465
|
-
if (hasAny([/\bupdate\b/, /\bpatch\b/, /\bset\b/, /\bmark\b/, /\bchange\b/, /cập nhật/, /đánh dấu/]))
|
|
466
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'update');
|
|
467
|
-
if (hasAny([/\bcreate\b/, /\binsert\b/, /\badd\b/, /\bstore\b/, /\bsave\b/, /tạo/, /thêm/, /lưu/]))
|
|
468
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'create');
|
|
469
|
-
if (hasAny([/\blog\b/, /\bdebug\b/, /\btrace\b/, /ghi log/]))
|
|
470
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'log');
|
|
471
|
-
if (hasAny([/\bquery\b/, /\bfind\b/, /\blist\b/, /\bread\b/, /\bload\b/, /\bcount\b/, /\bsearch\b/, /đọc/, /tìm/, /liệt kê/]))
|
|
472
|
-
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'query');
|
|
473
417
|
return FLOW_STEP_TOOL_GUIDANCE.find((item) => item.type === 'script');
|
|
474
418
|
}
|
|
475
|
-
const FIXED_FLOW_STEP_TYPES = new Set(['query', 'create', 'update', 'delete', 'http', 'sleep', 'trigger_flow', 'log']);
|
|
476
|
-
const FLOW_RUNTIME_MACRO_PATTERN = /@FLOW(?:_PAYLOAD|_LAST|_META)?\b/u;
|
|
477
|
-
function findFlowRuntimeMacro(value) {
|
|
478
|
-
if (typeof value === 'string')
|
|
479
|
-
return FLOW_RUNTIME_MACRO_PATTERN.exec(value)?.[0] || null;
|
|
480
|
-
if (Array.isArray(value)) {
|
|
481
|
-
for (const item of value) {
|
|
482
|
-
const match = findFlowRuntimeMacro(item);
|
|
483
|
-
if (match)
|
|
484
|
-
return match;
|
|
485
|
-
}
|
|
486
|
-
return null;
|
|
487
|
-
}
|
|
488
|
-
if (!value || typeof value !== 'object')
|
|
489
|
-
return null;
|
|
490
|
-
for (const item of Object.values(value)) {
|
|
491
|
-
const match = findFlowRuntimeMacro(item);
|
|
492
|
-
if (match)
|
|
493
|
-
return match;
|
|
494
|
-
}
|
|
495
|
-
return null;
|
|
496
|
-
}
|
|
497
|
-
export function assertFixedFlowStepConfigIsStatic(type, config, index = 0) {
|
|
498
|
-
if (!FIXED_FLOW_STEP_TYPES.has(String(type)))
|
|
499
|
-
return;
|
|
500
|
-
const macro = findFlowRuntimeMacro(config);
|
|
501
|
-
if (!macro)
|
|
502
|
-
return;
|
|
503
|
-
throw new Error(`steps[${index}] uses ${macro} inside a ${type} config, but ESV fixed flow step configs are static and are not template-transformed. Use a script step for runtime payload/previous-step values, keep one business operation in that script, and call @LOGS(message, details?) for captured logs.`);
|
|
504
|
-
}
|
|
505
419
|
export function planFlowSteps(steps) {
|
|
506
420
|
const items = Array.isArray(steps) ? steps : [];
|
|
507
421
|
return items.map((step, index) => {
|
|
@@ -518,9 +432,7 @@ export function planFlowSteps(steps) {
|
|
|
518
432
|
key,
|
|
519
433
|
name: typeof step === 'object' && step?.name ? step.name : key.replace(/_/g, ' '),
|
|
520
434
|
order: index + 1,
|
|
521
|
-
...(recommendation.config ? { config: recommendation.config } : {}),
|
|
522
435
|
...(recommendation.sourceCode ? { sourceCode: recommendation.sourceCode } : {}),
|
|
523
|
-
...(recommendation.condition ? { condition: recommendation.condition } : {}),
|
|
524
436
|
},
|
|
525
437
|
reason: recommendation.when,
|
|
526
438
|
};
|
|
@@ -548,7 +460,6 @@ function normalizeFlowWorkflowStep(step, index) {
|
|
|
548
460
|
intent,
|
|
549
461
|
type,
|
|
550
462
|
order: input.order ?? index * 10,
|
|
551
|
-
config: input.config ?? guidance.config ?? {},
|
|
552
463
|
sourceCode: input.sourceCode ?? (input.sourceFile || input.sourceResourceUri ? undefined : guidance.sourceCode),
|
|
553
464
|
sourceFile: input.sourceFile,
|
|
554
465
|
sourceResourceUri: input.sourceResourceUri,
|
|
@@ -558,7 +469,6 @@ function normalizeFlowWorkflowStep(step, index) {
|
|
|
558
469
|
chosenByIntent: !input.type,
|
|
559
470
|
recommendedTool: guidance.tool,
|
|
560
471
|
};
|
|
561
|
-
assertFixedFlowStepConfigIsStatic(type, normalized.config, index);
|
|
562
472
|
return normalized;
|
|
563
473
|
}
|
|
564
474
|
export async function runFlowWorkflow(apiUrl, opts) {
|
|
@@ -583,7 +493,7 @@ export async function runFlowWorkflow(apiUrl, opts) {
|
|
|
583
493
|
plan,
|
|
584
494
|
requiredAckParams: ['globalRulesAckKey', ...(hasDynamicCode ? ['knowledgeAckKey'] : [])],
|
|
585
495
|
nextSteps: [
|
|
586
|
-
'Review the plan.
|
|
496
|
+
'Review the plan. Flow steps are script-only; every query, mutation, HTTP call, delay, child-flow trigger, and log belongs in one focused script step.',
|
|
587
497
|
'Call flow_workflow again with apply=true and the required ack params to create/update the flow and steps sequentially.',
|
|
588
498
|
'Use test_flow_step for script, condition, or high-risk steps before triggering the flow.',
|
|
589
499
|
],
|
|
@@ -604,7 +514,6 @@ export async function runFlowWorkflow(apiUrl, opts) {
|
|
|
604
514
|
key: step.key,
|
|
605
515
|
type: step.type,
|
|
606
516
|
order: step.order,
|
|
607
|
-
config: step.config,
|
|
608
517
|
sourceCode: step.sourceCode,
|
|
609
518
|
sourceFile: step.sourceFile,
|
|
610
519
|
sourceResourceUri: step.sourceResourceUri,
|