snow-flow-test 10.0.1-test.158 → 10.0.1-test.159
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
|
@@ -311,6 +311,108 @@ async function addActionViaGraphQL(
|
|
|
311
311
|
}
|
|
312
312
|
}
|
|
313
313
|
|
|
314
|
+
// ── FLOW LOGIC (If/Else, For Each, etc.) ─────────────────────────────
|
|
315
|
+
|
|
316
|
+
async function addFlowLogicViaGraphQL(
|
|
317
|
+
client: any,
|
|
318
|
+
flowId: string,
|
|
319
|
+
logicType: string,
|
|
320
|
+
inputs?: Record<string, string>,
|
|
321
|
+
order?: number,
|
|
322
|
+
parentUiId?: string
|
|
323
|
+
): Promise<{ success: boolean; logicId?: string; steps?: any; error?: string }> {
|
|
324
|
+
const steps: any = {};
|
|
325
|
+
|
|
326
|
+
// Dynamically look up flow logic definition in sys_hub_flow_logic_definition
|
|
327
|
+
let defId: string | null = null;
|
|
328
|
+
let defName = '';
|
|
329
|
+
let defType = logicType;
|
|
330
|
+
// Try exact match on type (IF, FOR_EACH, DO_UNTIL, SWITCH), then name
|
|
331
|
+
for (const field of ['type', 'name']) {
|
|
332
|
+
if (defId) break;
|
|
333
|
+
try {
|
|
334
|
+
const resp = await client.get('/api/now/table/sys_hub_flow_logic_definition', {
|
|
335
|
+
params: { sysparm_query: field + '=' + logicType, sysparm_fields: 'sys_id,type,name,description', sysparm_limit: 1 }
|
|
336
|
+
});
|
|
337
|
+
const found = resp.data.result?.[0];
|
|
338
|
+
if (found?.sys_id) {
|
|
339
|
+
defId = found.sys_id;
|
|
340
|
+
defName = found.name || logicType;
|
|
341
|
+
defType = found.type || logicType;
|
|
342
|
+
steps.def_lookup = { id: found.sys_id, type: found.type, name: found.name, matched: field + '=' + logicType };
|
|
343
|
+
}
|
|
344
|
+
} catch (_) {}
|
|
345
|
+
}
|
|
346
|
+
// Fallback: LIKE search
|
|
347
|
+
if (!defId) {
|
|
348
|
+
try {
|
|
349
|
+
const resp = await client.get('/api/now/table/sys_hub_flow_logic_definition', {
|
|
350
|
+
params: {
|
|
351
|
+
sysparm_query: 'typeLIKE' + logicType + '^ORnameLIKE' + logicType,
|
|
352
|
+
sysparm_fields: 'sys_id,type,name,description', sysparm_limit: 5
|
|
353
|
+
}
|
|
354
|
+
});
|
|
355
|
+
const results = resp.data.result || [];
|
|
356
|
+
steps.def_lookup_fallback_candidates = results.map((r: any) => ({ sys_id: r.sys_id, type: r.type, name: r.name }));
|
|
357
|
+
if (results[0]?.sys_id) {
|
|
358
|
+
defId = results[0].sys_id;
|
|
359
|
+
defName = results[0].name || logicType;
|
|
360
|
+
defType = results[0].type || logicType;
|
|
361
|
+
steps.def_lookup = { id: results[0].sys_id, type: results[0].type, name: results[0].name, matched: 'LIKE ' + logicType };
|
|
362
|
+
}
|
|
363
|
+
} catch (_) {}
|
|
364
|
+
}
|
|
365
|
+
if (!defId) return { success: false, error: 'Flow logic definition not found for: ' + logicType, steps };
|
|
366
|
+
|
|
367
|
+
const uuid = generateUUID();
|
|
368
|
+
const logicResponseFields = 'flowLogics { inserts { sysId uiUniqueIdentifier __typename } updates deletes __typename }';
|
|
369
|
+
try {
|
|
370
|
+
const result = await executeFlowPatchMutation(client, {
|
|
371
|
+
flowId: flowId,
|
|
372
|
+
flowLogics: {
|
|
373
|
+
insert: [{
|
|
374
|
+
order: String(order || 1),
|
|
375
|
+
uiUniqueIdentifier: uuid,
|
|
376
|
+
parent: '',
|
|
377
|
+
metadata: '{"predicates":[]}',
|
|
378
|
+
flowSysId: flowId,
|
|
379
|
+
generationSource: '',
|
|
380
|
+
definitionId: defId,
|
|
381
|
+
type: 'flowlogic',
|
|
382
|
+
parentUiId: parentUiId || '',
|
|
383
|
+
inputs: []
|
|
384
|
+
}]
|
|
385
|
+
}
|
|
386
|
+
}, logicResponseFields);
|
|
387
|
+
|
|
388
|
+
const logicId = result?.flowLogics?.inserts?.[0]?.sysId;
|
|
389
|
+
steps.insert = { success: !!logicId, logicId, uuid };
|
|
390
|
+
if (!logicId) return { success: false, steps, error: 'GraphQL flow logic INSERT returned no ID' };
|
|
391
|
+
|
|
392
|
+
// Update with input values if provided
|
|
393
|
+
if (inputs && Object.keys(inputs).length > 0) {
|
|
394
|
+
const updateInputs = Object.entries(inputs).map(([name, value]) => ({
|
|
395
|
+
name,
|
|
396
|
+
value: { schemaless: false, schemalessValue: '', value: String(value) }
|
|
397
|
+
}));
|
|
398
|
+
try {
|
|
399
|
+
await executeFlowPatchMutation(client, {
|
|
400
|
+
flowId: flowId,
|
|
401
|
+
flowLogics: { update: [{ uiUniqueIdentifier: uuid, type: 'flowlogic', inputs: updateInputs }] }
|
|
402
|
+
}, logicResponseFields);
|
|
403
|
+
steps.value_update = { success: true, inputs: updateInputs.map(i => i.name) };
|
|
404
|
+
} catch (e: any) {
|
|
405
|
+
steps.value_update = { success: false, error: e.message };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
return { success: true, logicId, steps };
|
|
410
|
+
} catch (e: any) {
|
|
411
|
+
steps.insert = { success: false, error: e.message };
|
|
412
|
+
return { success: false, steps, error: 'GraphQL flow logic INSERT failed: ' + e.message };
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
314
416
|
async function createFlowViaProcessFlowAPI(
|
|
315
417
|
client: any,
|
|
316
418
|
params: {
|
|
@@ -419,8 +521,8 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
419
521
|
properties: {
|
|
420
522
|
action: {
|
|
421
523
|
type: 'string',
|
|
422
|
-
enum: ['create', 'create_subflow', 'list', 'get', 'update', 'activate', 'deactivate', 'delete', 'publish', 'add_trigger', 'update_trigger', 'add_action'],
|
|
423
|
-
description: 'Action to perform. Use add_trigger/add_action to add
|
|
524
|
+
enum: ['create', 'create_subflow', 'list', 'get', 'update', 'activate', 'deactivate', 'delete', 'publish', 'add_trigger', 'update_trigger', 'add_action', 'add_flow_logic'],
|
|
525
|
+
description: 'Action to perform. Use add_trigger/add_action/add_flow_logic to add elements, update_trigger to change an existing trigger. Flow logic types: IF, FOR_EACH, DO_UNTIL, SWITCH.'
|
|
424
526
|
},
|
|
425
527
|
|
|
426
528
|
flow_id: {
|
|
@@ -506,6 +608,18 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
506
608
|
description: 'Activate flow after creation (default: true)',
|
|
507
609
|
default: true
|
|
508
610
|
},
|
|
611
|
+
logic_type: {
|
|
612
|
+
type: 'string',
|
|
613
|
+
description: 'Flow logic type for add_flow_logic. Looked up dynamically in sys_hub_flow_logic_definition. Common values: IF, FOR_EACH, DO_UNTIL, SWITCH'
|
|
614
|
+
},
|
|
615
|
+
logic_inputs: {
|
|
616
|
+
type: 'object',
|
|
617
|
+
description: 'Input values for the flow logic block (e.g. {condition: "expression", condition_name: "My Condition"})'
|
|
618
|
+
},
|
|
619
|
+
parent_ui_id: {
|
|
620
|
+
type: 'string',
|
|
621
|
+
description: 'Parent UI unique identifier for nesting flow logic blocks (e.g. placing actions inside an If block)'
|
|
622
|
+
},
|
|
509
623
|
type: {
|
|
510
624
|
type: 'string',
|
|
511
625
|
enum: ['flow', 'subflow', 'all'],
|
|
@@ -1444,6 +1558,40 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
1444
1558
|
: createErrorResult(addActResult.error || 'Failed to add action');
|
|
1445
1559
|
}
|
|
1446
1560
|
|
|
1561
|
+
// ────────────────────────────────────────────────────────────────
|
|
1562
|
+
// ADD_FLOW_LOGIC — add If/Else, For Each, Do Until, Switch blocks
|
|
1563
|
+
// ────────────────────────────────────────────────────────────────
|
|
1564
|
+
case 'add_flow_logic': {
|
|
1565
|
+
if (!args.flow_id) {
|
|
1566
|
+
throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'flow_id is required for add_flow_logic');
|
|
1567
|
+
}
|
|
1568
|
+
if (!args.logic_type) {
|
|
1569
|
+
throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'logic_type is required for add_flow_logic (e.g. IF, FOR_EACH, DO_UNTIL, SWITCH)');
|
|
1570
|
+
}
|
|
1571
|
+
var addLogicFlowId = await resolveFlowId(client, args.flow_id);
|
|
1572
|
+
var addLogicType = args.logic_type;
|
|
1573
|
+
var addLogicInputs = args.logic_inputs || {};
|
|
1574
|
+
var addLogicOrder = args.order;
|
|
1575
|
+
var addLogicParentUiId = args.parent_ui_id || '';
|
|
1576
|
+
|
|
1577
|
+
var addLogicResult = await addFlowLogicViaGraphQL(client, addLogicFlowId, addLogicType, addLogicInputs, addLogicOrder, addLogicParentUiId);
|
|
1578
|
+
|
|
1579
|
+
var addLogicSummary = summary();
|
|
1580
|
+
if (addLogicResult.success) {
|
|
1581
|
+
addLogicSummary
|
|
1582
|
+
.success('Flow logic added via GraphQL')
|
|
1583
|
+
.field('Flow', addLogicFlowId)
|
|
1584
|
+
.field('Type', addLogicType)
|
|
1585
|
+
.field('Logic ID', addLogicResult.logicId || 'unknown');
|
|
1586
|
+
} else {
|
|
1587
|
+
addLogicSummary.error('Failed to add flow logic: ' + (addLogicResult.error || 'unknown'));
|
|
1588
|
+
}
|
|
1589
|
+
|
|
1590
|
+
return addLogicResult.success
|
|
1591
|
+
? createSuccessResult({ action: 'add_flow_logic', ...addLogicResult }, {}, addLogicSummary.build())
|
|
1592
|
+
: createErrorResult(addLogicResult.error || 'Failed to add flow logic');
|
|
1593
|
+
}
|
|
1594
|
+
|
|
1447
1595
|
default:
|
|
1448
1596
|
throw new SnowFlowError(ErrorType.VALIDATION_ERROR, 'Unknown action: ' + action);
|
|
1449
1597
|
}
|