snow-flow 10.0.1-dev.486 → 10.0.1-dev.488

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
- "version": "10.0.1-dev.486",
3
+ "version": "10.0.1-dev.488",
4
4
  "name": "snow-flow",
5
5
  "description": "Snow-Flow - ServiceNow Multi-Agent Development Framework powered by AI",
6
6
  "license": "Elastic-2.0",
@@ -1917,6 +1917,27 @@ async function addFlowLogicViaGraphQL(
1917
1917
  ): Promise<{ success: boolean; logicId?: string; uiUniqueIdentifier?: string; steps?: any; error?: string }> {
1918
1918
  const steps: any = {};
1919
1919
 
1920
+ // Normalize common aliases to actual ServiceNow flow logic type values
1921
+ var LOGIC_TYPE_ALIASES: Record<string, string> = {
1922
+ 'FOR_EACH': 'FOREACH',
1923
+ 'DO_UNTIL': 'DOUNTIL',
1924
+ 'ELSE_IF': 'ELSEIF',
1925
+ 'SKIP_ITERATION': 'CONTINUE',
1926
+ 'EXIT_LOOP': 'BREAK',
1927
+ 'GO_BACK_TO': 'GOBACKTO',
1928
+ 'DYNAMIC_FLOW': 'DYNAMICFLOW',
1929
+ 'END_FLOW': 'END',
1930
+ 'GET_FLOW_OUTPUT': 'GETFLOWOUTPUT',
1931
+ 'GET_FLOW_OUTPUTS': 'GETFLOWOUTPUT',
1932
+ 'SET_FLOW_VARIABLES': 'SETFLOWVARIABLES',
1933
+ 'APPEND_FLOW_VARIABLES': 'APPENDFLOWVARIABLES',
1934
+ };
1935
+ var normalizedType = LOGIC_TYPE_ALIASES[logicType.toUpperCase()] || logicType;
1936
+ if (normalizedType !== logicType) {
1937
+ steps.type_normalized = { from: logicType, to: normalizedType };
1938
+ logicType = normalizedType;
1939
+ }
1940
+
1920
1941
  // Dynamically look up flow logic definition in sys_hub_flow_logic_definition
1921
1942
  // Fetch extra fields needed for the flowLogicDefinition object in the mutation
1922
1943
  const defFields = 'sys_id,type,name,description,order,attributes,compilation_class,quiescence,visible,category,connected_to';
@@ -1924,7 +1945,7 @@ async function addFlowLogicViaGraphQL(
1924
1945
  let defName = '';
1925
1946
  let defType = logicType;
1926
1947
  let defRecord: any = {};
1927
- // Try exact match on type (IF, ELSE, FOR_EACH, DO_UNTIL, SWITCH), then name
1948
+ // Try exact match on type (IF, ELSE, FOREACH, DOUNTIL, etc.), then name
1928
1949
  for (const field of ['type', 'name']) {
1929
1950
  if (defId) break;
1930
1951
  try {
@@ -2506,9 +2527,10 @@ export const toolDefinition: MCPToolDefinition = {
2506
2527
  'add_action', 'update_action', 'delete_action',
2507
2528
  'add_flow_logic', 'update_flow_logic', 'delete_flow_logic',
2508
2529
  'add_subflow', 'update_subflow', 'delete_subflow',
2509
- 'close_flow'
2530
+ 'open_flow', 'close_flow'
2510
2531
  ],
2511
- description: 'Action to perform. add_*/update_*/delete_* for triggers, actions, flow_logic, subflows. update_trigger replaces the trigger type. update_action/update_flow_logic/update_subflow change input values. delete_* removes elements by element_id. IMPORTANT: When making multiple edits to a flow (add_action, add_flow_logic, etc.), call close_flow as the LAST step to release the editing lock. Without close_flow, the flow stays locked and cannot be edited in the UI. create_flow auto-releases the lock.'
2532
+ description: 'Action to perform. EDITING WORKFLOW: create_flow keeps the editing lock open you can immediately call add_action, add_flow_logic, etc. without open_flow. For editing EXISTING flows: call open_flow first to acquire the lock. Always call close_flow as the LAST step to release the lock so users can edit in the UI. ' +
2533
+ 'add_*/update_*/delete_* for triggers, actions, flow_logic, subflows. update_trigger replaces the trigger type. delete_* removes elements by element_id.'
2512
2534
  },
2513
2535
 
2514
2536
  flow_id: {
@@ -2596,17 +2618,18 @@ export const toolDefinition: MCPToolDefinition = {
2596
2618
  },
2597
2619
  logic_type: {
2598
2620
  type: 'string',
2599
- description: 'Flow logic type for add_flow_logic. Looked up dynamically in sys_hub_flow_logic_definition. Available types: ' +
2621
+ description: 'Flow logic type for add_flow_logic. Looked up dynamically in sys_hub_flow_logic_definition. ' +
2622
+ 'Common aliases (FOR_EACH, DO_UNTIL, etc.) are auto-normalized to ServiceNow types. Available types: ' +
2600
2623
  'IF, ELSEIF, ELSE — conditional branching. Use ELSEIF (not nested ELSE+IF) for else-if branches. ELSE and ELSEIF require connected_to set to the If block\'s uiUniqueIdentifier. ' +
2601
- 'FOR_EACH, DO_UNTIL — loops. SKIP_ITERATION and EXIT_LOOP can be used inside loops. ' +
2624
+ 'FOREACH (or FOR_EACH), DOUNTIL (or DO_UNTIL) — loops. CONTINUE (skip iteration) and BREAK (exit loop) can be used inside loops. ' +
2602
2625
  'PARALLEL — execute branches in parallel. ' +
2603
2626
  'DECISION — switch/decision table. ' +
2604
2627
  'TRY — error handling (try/catch). ' +
2605
2628
  'END — End Flow (stops execution). Always add END as the last element when the flow should terminate cleanly. ' +
2606
2629
  'TIMER — Wait for a duration of time. ' +
2607
- 'GO_BACK_TO — jump back to a previous step. ' +
2608
- 'SET_FLOW_VARIABLES, APPEND_FLOW_VARIABLES, GET_FLOW_OUTPUT — flow variable management. ' +
2609
- 'WORKFLOW — call a legacy workflow. DYNAMIC_FLOW — dynamically invoke a flow. ' +
2630
+ 'GOBACKTO (or GO_BACK_TO) — jump back to a previous step. ' +
2631
+ 'SETFLOWVARIABLES, APPENDFLOWVARIABLES, GETFLOWOUTPUT — flow variable management. ' +
2632
+ 'WORKFLOW — call a legacy workflow. DYNAMICFLOW — dynamically invoke a flow. ' +
2610
2633
  'Best practice: add an END element at the end of your flow for clean termination.'
2611
2634
  },
2612
2635
  logic_inputs: {
@@ -3094,11 +3117,8 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
3094
3117
  }
3095
3118
  }
3096
3119
 
3097
- // Release Flow Designer editing lock (safeEdit delete) so users can edit the flow in the UI
3098
- if (flowSysId) {
3099
- var lockReleased = await releaseFlowEditingLock(client, flowSysId);
3100
- diagnostics.editing_lock_released = lockReleased;
3101
- }
3120
+ // NOTE: Do NOT release the editing lock here. The agent may need to add more elements
3121
+ // (flow logic, actions, etc.) after creation. The agent must call close_flow when done.
3102
3122
 
3103
3123
  return createSuccessResult({
3104
3124
  created: true,
@@ -3706,6 +3726,26 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
3706
3726
  : createErrorResult(delResult.error || 'Failed to delete element');
3707
3727
  }
3708
3728
 
3729
+ // ────────────────────────────────────────────────────────────────
3730
+ // OPEN_FLOW — acquire Flow Designer editing lock (processflow GET)
3731
+ // ────────────────────────────────────────────────────────────────
3732
+ case 'open_flow': {
3733
+ if (!args.flow_id) throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'flow_id is required for open_flow');
3734
+ var openFlowId = await resolveFlowId(client, args.flow_id);
3735
+ var openSummary = summary();
3736
+ try {
3737
+ // The processflow GET is what the Flow Designer UI calls when opening a flow for editing.
3738
+ // This acquires the editing lock so subsequent GraphQL mutations can work.
3739
+ await client.get('/api/now/processflow/flow/' + openFlowId);
3740
+ openSummary.success('Flow opened for editing').field('Flow', openFlowId)
3741
+ .line('You can now use add_action, add_flow_logic, etc. Call close_flow when done.');
3742
+ return createSuccessResult({ action: 'open_flow', flow_id: openFlowId, editing_session: true }, {}, openSummary.build());
3743
+ } catch (e: any) {
3744
+ openSummary.error('Failed to open flow for editing: ' + (e.message || 'unknown')).field('Flow', openFlowId);
3745
+ return createErrorResult('Failed to open flow for editing: ' + (e.message || 'unknown'));
3746
+ }
3747
+ }
3748
+
3709
3749
  // ────────────────────────────────────────────────────────────────
3710
3750
  // CLOSE_FLOW — release Flow Designer editing lock (safeEdit)
3711
3751
  // ────────────────────────────────────────────────────────────────