snow-flow-test 10.0.1-test.172 → 10.0.1-test.176
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
|
@@ -206,20 +206,39 @@ async function buildFlowLogicInputsForInsert(
|
|
|
206
206
|
defId: string,
|
|
207
207
|
defRecord: { name?: string; type?: string; description?: string; order?: string; attributes?: string; compilation_class?: string; quiescence?: string; visible?: string; category?: string; connected_to?: string },
|
|
208
208
|
userValues?: Record<string, string>
|
|
209
|
-
): Promise<{ inputs: any[]; flowLogicDefinition: any; resolvedInputs: Record<string, string
|
|
209
|
+
): Promise<{ inputs: any[]; flowLogicDefinition: any; resolvedInputs: Record<string, string>; inputQueryError?: string; defParamsCount: number }> {
|
|
210
210
|
// Query sys_hub_flow_logic_input for this definition's inputs (separate table from sys_hub_action_input)
|
|
211
|
+
// Field names verified from actual sys_hub_flow_logic_input XML schema
|
|
211
212
|
var defParams: any[] = [];
|
|
213
|
+
var inputQueryError = '';
|
|
212
214
|
try {
|
|
213
215
|
var resp = await client.get('/api/now/table/sys_hub_flow_logic_input', {
|
|
214
216
|
params: {
|
|
215
217
|
sysparm_query: 'model=' + defId,
|
|
216
|
-
sysparm_fields: 'sys_id,element,label,internal_type,mandatory,default_value,order,max_length,hint,read_only,
|
|
218
|
+
sysparm_fields: 'sys_id,element,label,internal_type,mandatory,default_value,order,max_length,hint,read_only,attributes,sys_class_name,reference,choice,dependent,dependent_on_field,use_dependent_field,column_label',
|
|
217
219
|
sysparm_display_value: 'false',
|
|
218
220
|
sysparm_limit: 50
|
|
219
221
|
}
|
|
220
222
|
});
|
|
221
223
|
defParams = resp.data.result || [];
|
|
222
|
-
} catch (
|
|
224
|
+
} catch (e: any) {
|
|
225
|
+
inputQueryError = e.message || 'unknown error';
|
|
226
|
+
// Fallback: try with minimal fields
|
|
227
|
+
try {
|
|
228
|
+
var resp2 = await client.get('/api/now/table/sys_hub_flow_logic_input', {
|
|
229
|
+
params: {
|
|
230
|
+
sysparm_query: 'model=' + defId,
|
|
231
|
+
sysparm_fields: 'sys_id,element,label,internal_type,mandatory,order,max_length,attributes',
|
|
232
|
+
sysparm_display_value: 'false',
|
|
233
|
+
sysparm_limit: 50
|
|
234
|
+
}
|
|
235
|
+
});
|
|
236
|
+
defParams = resp2.data.result || [];
|
|
237
|
+
inputQueryError = '';
|
|
238
|
+
} catch (e2: any) {
|
|
239
|
+
inputQueryError += '; fallback also failed: ' + (e2.message || '');
|
|
240
|
+
}
|
|
241
|
+
}
|
|
223
242
|
|
|
224
243
|
// Fuzzy-match user-provided values to actual field names
|
|
225
244
|
var resolvedInputs: Record<string, string> = {};
|
|
@@ -304,7 +323,7 @@ async function buildFlowLogicInputsForInsert(
|
|
|
304
323
|
variables: '[]'
|
|
305
324
|
};
|
|
306
325
|
|
|
307
|
-
return { inputs, flowLogicDefinition, resolvedInputs };
|
|
326
|
+
return { inputs, flowLogicDefinition, resolvedInputs, inputQueryError: inputQueryError || undefined, defParamsCount: defParams.length };
|
|
308
327
|
}
|
|
309
328
|
|
|
310
329
|
// Note: reordering of existing elements is NOT possible via Table API because
|
|
@@ -446,7 +465,8 @@ async function addTriggerViaGraphQL(
|
|
|
446
465
|
},
|
|
447
466
|
{
|
|
448
467
|
name: 'condition',
|
|
449
|
-
displayValue: { schemaless: false, schemalessValue: '', value: condition || '^EQ' }
|
|
468
|
+
displayValue: { schemaless: false, schemalessValue: '', value: condition || '^EQ' },
|
|
469
|
+
value: { schemaless: false, schemalessValue: '', value: condition || '^EQ' }
|
|
450
470
|
}
|
|
451
471
|
];
|
|
452
472
|
try {
|
|
@@ -474,22 +494,53 @@ async function addActionViaGraphQL(
|
|
|
474
494
|
actionName: string,
|
|
475
495
|
inputs?: Record<string, string>,
|
|
476
496
|
parentUiId?: string,
|
|
477
|
-
order?: number
|
|
497
|
+
order?: number,
|
|
498
|
+
spoke?: string
|
|
478
499
|
): Promise<{ success: boolean; actionId?: string; steps?: any; error?: string }> {
|
|
479
500
|
const steps: any = {};
|
|
480
501
|
|
|
481
502
|
// Dynamically look up action definition in sys_hub_action_type_snapshot
|
|
503
|
+
// Prefer global/core actions over spoke-specific ones (e.g. core "Update Record" vs spoke-specific "Update Record")
|
|
504
|
+
const snapshotFields = 'sys_id,internal_name,name,sys_scope,sys_package';
|
|
482
505
|
let actionDefId: string | null = null;
|
|
506
|
+
|
|
507
|
+
// Helper: pick the best match from candidates — prefer spoke filter, then global scope
|
|
508
|
+
const pickBest = (candidates: any[]): any => {
|
|
509
|
+
if (!candidates || candidates.length === 0) return null;
|
|
510
|
+
if (candidates.length === 1) return candidates[0];
|
|
511
|
+
// If spoke filter is specified, match against scope or package name
|
|
512
|
+
if (spoke) {
|
|
513
|
+
var spokeLC = spoke.toLowerCase();
|
|
514
|
+
var spokeMatch = candidates.find((c: any) =>
|
|
515
|
+
str(c.sys_scope).toLowerCase().includes(spokeLC) ||
|
|
516
|
+
str(c.sys_package).toLowerCase().includes(spokeLC) ||
|
|
517
|
+
str(c.internal_name).toLowerCase().includes(spokeLC)
|
|
518
|
+
);
|
|
519
|
+
if (spokeMatch) return spokeMatch;
|
|
520
|
+
}
|
|
521
|
+
// Prefer global scope
|
|
522
|
+
var global = candidates.find((c: any) => str(c.sys_scope) === 'global' || str(c.sys_scope) === 'rhino.global');
|
|
523
|
+
if (global) return global;
|
|
524
|
+
// Prefer records without "spoke" in the package name
|
|
525
|
+
var nonSpoke = candidates.find((c: any) => !str(c.sys_package).toLowerCase().includes('spoke'));
|
|
526
|
+
if (nonSpoke) return nonSpoke;
|
|
527
|
+
return candidates[0];
|
|
528
|
+
};
|
|
529
|
+
|
|
483
530
|
for (const field of ['internal_name', 'name']) {
|
|
484
531
|
if (actionDefId) break;
|
|
485
532
|
try {
|
|
486
533
|
const resp = await client.get('/api/now/table/sys_hub_action_type_snapshot', {
|
|
487
|
-
params: { sysparm_query: field + '=' + actionType, sysparm_fields:
|
|
534
|
+
params: { sysparm_query: field + '=' + actionType, sysparm_fields: snapshotFields, sysparm_limit: 10 }
|
|
488
535
|
});
|
|
489
|
-
const
|
|
536
|
+
const results = resp.data.result || [];
|
|
537
|
+
if (results.length > 1) {
|
|
538
|
+
steps.def_lookup_candidates = results.map((r: any) => ({ sys_id: r.sys_id, internal_name: str(r.internal_name), name: str(r.name), scope: str(r.sys_scope), package: str(r.sys_package) }));
|
|
539
|
+
}
|
|
540
|
+
const found = pickBest(results);
|
|
490
541
|
if (found?.sys_id) {
|
|
491
542
|
actionDefId = found.sys_id;
|
|
492
|
-
steps.def_lookup = { id: found.sys_id, internal_name: found.internal_name, name: found.name, matched: field + '=' + actionType };
|
|
543
|
+
steps.def_lookup = { id: found.sys_id, internal_name: str(found.internal_name), name: str(found.name), scope: str(found.sys_scope), package: str(found.sys_package), matched: field + '=' + actionType };
|
|
493
544
|
}
|
|
494
545
|
} catch (_) {}
|
|
495
546
|
}
|
|
@@ -498,14 +549,15 @@ async function addActionViaGraphQL(
|
|
|
498
549
|
const resp = await client.get('/api/now/table/sys_hub_action_type_snapshot', {
|
|
499
550
|
params: {
|
|
500
551
|
sysparm_query: 'internal_nameLIKE' + actionType + '^ORnameLIKE' + actionType,
|
|
501
|
-
sysparm_fields:
|
|
552
|
+
sysparm_fields: snapshotFields, sysparm_limit: 10
|
|
502
553
|
}
|
|
503
554
|
});
|
|
504
555
|
const results = resp.data.result || [];
|
|
505
|
-
steps.def_lookup_fallback_candidates = results.map((r: any) => ({ sys_id: r.sys_id, internal_name: r.internal_name, name: r.name }));
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
556
|
+
steps.def_lookup_fallback_candidates = results.map((r: any) => ({ sys_id: r.sys_id, internal_name: str(r.internal_name), name: str(r.name), scope: str(r.sys_scope), package: str(r.sys_package) }));
|
|
557
|
+
const found = pickBest(results);
|
|
558
|
+
if (found?.sys_id) {
|
|
559
|
+
actionDefId = found.sys_id;
|
|
560
|
+
steps.def_lookup = { id: found.sys_id, internal_name: str(found.internal_name), name: str(found.name), scope: str(found.sys_scope), package: str(found.sys_package), matched: 'LIKE ' + actionType };
|
|
509
561
|
}
|
|
510
562
|
} catch (_) {}
|
|
511
563
|
}
|
|
@@ -630,6 +682,7 @@ async function addFlowLogicViaGraphQL(
|
|
|
630
682
|
const inputResult = await buildFlowLogicInputsForInsert(client, defId, defRecord, inputs);
|
|
631
683
|
steps.available_inputs = inputResult.inputs.map((i: any) => ({ name: i.name, label: i.parameter?.label }));
|
|
632
684
|
steps.resolved_inputs = inputResult.resolvedInputs;
|
|
685
|
+
steps.input_query_stats = { defParamsFound: inputResult.defParamsCount, inputsBuilt: inputResult.inputs.length, error: inputResult.inputQueryError };
|
|
633
686
|
|
|
634
687
|
// Calculate insertion order
|
|
635
688
|
const resolvedOrder = await calculateInsertOrder(client, flowId, parentUiId, order);
|
|
@@ -1106,6 +1159,10 @@ export const toolDefinition: MCPToolDefinition = {
|
|
|
1106
1159
|
type: 'string',
|
|
1107
1160
|
description: 'Display name for the action (for add_action)'
|
|
1108
1161
|
},
|
|
1162
|
+
spoke: {
|
|
1163
|
+
type: 'string',
|
|
1164
|
+
description: 'Spoke/scope filter for action lookup (for add_action). Use to disambiguate when multiple spokes have actions with the same name (e.g. "global" for core actions, "spoke-specific" for spoke-specific Spoke actions). Matched against sys_scope and sys_package fields.'
|
|
1165
|
+
},
|
|
1109
1166
|
action_inputs: {
|
|
1110
1167
|
type: 'object',
|
|
1111
1168
|
description: 'Key-value pairs for action inputs (e.g. {log_message: "test", log_level: "info"})'
|
|
@@ -1999,7 +2056,7 @@ export async function execute(args: any, context: ServiceNowContext): Promise<To
|
|
|
1999
2056
|
var addActName = args.action_name || args.name || addActType;
|
|
2000
2057
|
var addActInputs = args.action_inputs || args.inputs || {};
|
|
2001
2058
|
|
|
2002
|
-
var addActResult = await addActionViaGraphQL(client, addActFlowId, addActType, addActName, addActInputs, args.parent_ui_id, args.order);
|
|
2059
|
+
var addActResult = await addActionViaGraphQL(client, addActFlowId, addActType, addActName, addActInputs, args.parent_ui_id, args.order, args.spoke);
|
|
2003
2060
|
|
|
2004
2061
|
var addActSummary = summary();
|
|
2005
2062
|
if (addActResult.success) {
|