powerautomate-mcp 0.8.0 → 0.9.0
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/index.js +311 -37
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1518,6 +1518,30 @@ var FlowManagementApi = class {
|
|
|
1518
1518
|
return data;
|
|
1519
1519
|
}, "Fetch resource link");
|
|
1520
1520
|
}
|
|
1521
|
+
async getFlowRunActionRepetitions(flowId, runId, actionName, environmentId) {
|
|
1522
|
+
const envId = environmentId ?? this.defaultEnvironmentId;
|
|
1523
|
+
const safeFlowId = validateRowId(flowId);
|
|
1524
|
+
const safeRunId = validateFlowRunId(runId);
|
|
1525
|
+
const safeActionName = encodeURIComponent(actionName);
|
|
1526
|
+
apiLogger.debug({ flowId: safeFlowId, runId: safeRunId, actionName }, "Getting action repetitions");
|
|
1527
|
+
const url = this.buildUrl(
|
|
1528
|
+
envId,
|
|
1529
|
+
`/flows/${safeFlowId}/runs/${safeRunId}/actions/${safeActionName}/repetitions`
|
|
1530
|
+
);
|
|
1531
|
+
const headers = await this.getAuthHeaders();
|
|
1532
|
+
return wrapApiCall(async () => {
|
|
1533
|
+
const response = await request(url, { method: "GET", headers });
|
|
1534
|
+
const data = await this.handleResponse(
|
|
1535
|
+
response,
|
|
1536
|
+
`Get repetitions for action ${actionName}`
|
|
1537
|
+
);
|
|
1538
|
+
apiLogger.info(
|
|
1539
|
+
{ flowId, runId, actionName, count: data.value.length },
|
|
1540
|
+
"Retrieved action repetitions"
|
|
1541
|
+
);
|
|
1542
|
+
return data.value;
|
|
1543
|
+
}, `Get repetitions for action ${actionName}`);
|
|
1544
|
+
}
|
|
1521
1545
|
// ==========================================================================
|
|
1522
1546
|
// Flow Sharing & Permissions
|
|
1523
1547
|
// ==========================================================================
|
|
@@ -6872,11 +6896,14 @@ var getRunActionsInputSchema = z.object({
|
|
|
6872
6896
|
flowId: z.string().describe("The flow ID (GUID)"),
|
|
6873
6897
|
runId: z.string().describe("The run ID (GUID)"),
|
|
6874
6898
|
environment: z.string().optional().describe("Environment name or GUID. Uses default if omitted."),
|
|
6875
|
-
failedOnly: z.boolean().optional().describe("If true, only return failed actions (default: false)")
|
|
6899
|
+
failedOnly: z.boolean().optional().describe("If true, only return failed actions (default: false)"),
|
|
6900
|
+
includeInputs: z.boolean().optional().describe("If true, fetch and display input data for each action (default: false for succeeded, true for failed)"),
|
|
6901
|
+
includeOutputs: z.boolean().optional().describe("If true, fetch and display output data for each action (default: false for succeeded, true for failed)"),
|
|
6902
|
+
actionName: z.string().optional().describe("Filter to a specific action by name (partial match). Use to drill into one action's details.")
|
|
6876
6903
|
});
|
|
6877
6904
|
var getRunActionsTool = {
|
|
6878
6905
|
name: "get_run_actions",
|
|
6879
|
-
description: "Get detailed action-level information for a flow run. Shows each action's status, timing, and
|
|
6906
|
+
description: "Get detailed action-level information for a flow run. Shows each action's status, timing, inputs/outputs, and error details. Use 'failedOnly: true' to focus on failures, 'actionName' to drill into a specific action, 'includeInputs'/'includeOutputs' to see full data payloads.",
|
|
6880
6907
|
inputSchema: {
|
|
6881
6908
|
type: "object",
|
|
6882
6909
|
properties: {
|
|
@@ -6895,11 +6922,34 @@ var getRunActionsTool = {
|
|
|
6895
6922
|
failedOnly: {
|
|
6896
6923
|
type: "boolean",
|
|
6897
6924
|
description: "If true, only return failed actions (default: false)"
|
|
6925
|
+
},
|
|
6926
|
+
includeInputs: {
|
|
6927
|
+
type: "boolean",
|
|
6928
|
+
description: "If true, fetch and display input data for each action (default: false for succeeded, true for failed)"
|
|
6929
|
+
},
|
|
6930
|
+
includeOutputs: {
|
|
6931
|
+
type: "boolean",
|
|
6932
|
+
description: "If true, fetch and display output data for each action (default: false for succeeded, true for failed)"
|
|
6933
|
+
},
|
|
6934
|
+
actionName: {
|
|
6935
|
+
type: "string",
|
|
6936
|
+
description: "Filter to a specific action by name (partial match). Use to drill into one action's details."
|
|
6898
6937
|
}
|
|
6899
6938
|
},
|
|
6900
6939
|
required: ["flowId", "runId"]
|
|
6901
6940
|
}
|
|
6902
6941
|
};
|
|
6942
|
+
var TRUNCATE_LIMIT = 1e3;
|
|
6943
|
+
var ERROR_TRUNCATE_LIMIT = 500;
|
|
6944
|
+
function formatResourceData(data) {
|
|
6945
|
+
if (data && typeof data === "object" && "body" in data) {
|
|
6946
|
+
const body = data.body;
|
|
6947
|
+
const str2 = typeof body === "object" ? JSON.stringify(body, null, 2) : String(body);
|
|
6948
|
+
return str2.length > TRUNCATE_LIMIT ? str2.slice(0, TRUNCATE_LIMIT) + "\u2026" : str2;
|
|
6949
|
+
}
|
|
6950
|
+
const str = JSON.stringify(data, null, 2);
|
|
6951
|
+
return str.length > TRUNCATE_LIMIT ? str.slice(0, TRUNCATE_LIMIT) + "\u2026" : str;
|
|
6952
|
+
}
|
|
6903
6953
|
async function handleGetRunActions(api, input) {
|
|
6904
6954
|
const parsed = getRunActionsInputSchema.parse(input);
|
|
6905
6955
|
logger.info({ input: parsed }, "Executing get_run_actions");
|
|
@@ -6909,38 +6959,70 @@ async function handleGetRunActions(api, input) {
|
|
|
6909
6959
|
parsed.environment
|
|
6910
6960
|
);
|
|
6911
6961
|
let filteredActions = actions;
|
|
6962
|
+
if (parsed.actionName) {
|
|
6963
|
+
const needle = parsed.actionName.toLowerCase();
|
|
6964
|
+
filteredActions = filteredActions.filter(
|
|
6965
|
+
(a) => a.name.toLowerCase().includes(needle)
|
|
6966
|
+
);
|
|
6967
|
+
}
|
|
6912
6968
|
if (parsed.failedOnly) {
|
|
6913
|
-
filteredActions =
|
|
6969
|
+
filteredActions = filteredActions.filter(
|
|
6914
6970
|
(a) => a.properties.status === "Failed" || a.properties.status === "TimedOut"
|
|
6915
6971
|
);
|
|
6916
6972
|
}
|
|
6917
|
-
const
|
|
6918
|
-
|
|
6973
|
+
const shouldFetchInputs = (status) => {
|
|
6974
|
+
if (parsed.includeInputs === true) return true;
|
|
6975
|
+
if (parsed.includeInputs === false) return false;
|
|
6976
|
+
return status === "Failed" || status === "TimedOut";
|
|
6977
|
+
};
|
|
6978
|
+
const shouldFetchOutputs = (status) => {
|
|
6979
|
+
if (parsed.includeOutputs === true) return true;
|
|
6980
|
+
if (parsed.includeOutputs === false) return false;
|
|
6981
|
+
return status === "Failed" || status === "TimedOut";
|
|
6982
|
+
};
|
|
6983
|
+
const actionIO = {};
|
|
6984
|
+
const fetchPromises = [];
|
|
6919
6985
|
for (const action of filteredActions) {
|
|
6920
|
-
const
|
|
6921
|
-
|
|
6922
|
-
|
|
6986
|
+
const status = action.properties.status;
|
|
6987
|
+
const needInputs = shouldFetchInputs(status) && action.properties.inputsLink?.uri;
|
|
6988
|
+
const needOutputs = shouldFetchOutputs(status) && action.properties.outputsLink?.uri;
|
|
6989
|
+
if (needInputs) {
|
|
6990
|
+
fetchPromises.push(
|
|
6991
|
+
api.fetchResourceLink(action.properties.inputsLink.uri).then(
|
|
6992
|
+
(data) => {
|
|
6993
|
+
if (!actionIO[action.name]) actionIO[action.name] = {};
|
|
6994
|
+
actionIO[action.name].inputs = formatResourceData(data);
|
|
6995
|
+
},
|
|
6996
|
+
(err) => {
|
|
6997
|
+
if (!actionIO[action.name]) actionIO[action.name] = {};
|
|
6998
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
6999
|
+
actionIO[action.name].inputs = `(fetch error: ${msg.slice(0, 100)})`;
|
|
7000
|
+
}
|
|
7001
|
+
)
|
|
7002
|
+
);
|
|
6923
7003
|
}
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
6930
|
-
|
|
6931
|
-
|
|
6932
|
-
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
7004
|
+
if (needOutputs) {
|
|
7005
|
+
fetchPromises.push(
|
|
7006
|
+
api.fetchResourceLink(action.properties.outputsLink.uri).then(
|
|
7007
|
+
(data) => {
|
|
7008
|
+
if (!actionIO[action.name]) actionIO[action.name] = {};
|
|
7009
|
+
actionIO[action.name].outputs = formatResourceData(data);
|
|
7010
|
+
},
|
|
7011
|
+
(err) => {
|
|
7012
|
+
if (!actionIO[action.name]) actionIO[action.name] = {};
|
|
7013
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7014
|
+
actionIO[action.name].outputs = `(fetch error: ${msg.slice(0, 100)})`;
|
|
7015
|
+
}
|
|
7016
|
+
)
|
|
7017
|
+
);
|
|
6938
7018
|
}
|
|
6939
7019
|
}
|
|
6940
|
-
|
|
7020
|
+
await Promise.all(fetchPromises);
|
|
7021
|
+
const results = filteredActions.map((action) => {
|
|
6941
7022
|
const props = action.properties;
|
|
6942
7023
|
const startTime = new Date(props.startTime);
|
|
6943
7024
|
const endTime = props.endTime ? new Date(props.endTime) : void 0;
|
|
7025
|
+
const io = actionIO[action.name];
|
|
6944
7026
|
return {
|
|
6945
7027
|
name: action.name,
|
|
6946
7028
|
status: props.status,
|
|
@@ -6948,25 +7030,213 @@ async function handleGetRunActions(api, input) {
|
|
|
6948
7030
|
endTime: props.endTime,
|
|
6949
7031
|
durationMs: endTime ? endTime.getTime() - startTime.getTime() : void 0,
|
|
6950
7032
|
error: props.error,
|
|
6951
|
-
|
|
7033
|
+
inputs: io?.inputs,
|
|
7034
|
+
outputs: io?.outputs,
|
|
7035
|
+
retryCount: props.retryHistory?.length,
|
|
7036
|
+
trackedProperties: props.trackedProperties
|
|
6952
7037
|
};
|
|
6953
7038
|
});
|
|
6954
|
-
const failedCount =
|
|
6955
|
-
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
|
|
6959
|
-
|
|
6960
|
-
|
|
6961
|
-
}
|
|
6962
|
-
|
|
7039
|
+
const failedCount = results.filter(
|
|
7040
|
+
(r) => r.status === "Failed" || r.status === "TimedOut"
|
|
7041
|
+
).length;
|
|
7042
|
+
const succeededCount = results.filter(
|
|
7043
|
+
(r) => r.status === "Succeeded"
|
|
7044
|
+
).length;
|
|
7045
|
+
const lines = [
|
|
7046
|
+
`Actions: ${results.length} total (${succeededCount} succeeded, ${failedCount} failed)`
|
|
7047
|
+
];
|
|
7048
|
+
if (parsed.actionName) {
|
|
7049
|
+
lines[0] += ` [filtered by "${parsed.actionName}"]`;
|
|
6963
7050
|
}
|
|
6964
|
-
for (const action of
|
|
7051
|
+
for (const action of results) {
|
|
6965
7052
|
const duration = action.durationMs ? `${(action.durationMs / 1e3).toFixed(1)}s` : "";
|
|
6966
|
-
const status = action.status === "Succeeded" ? "\u2713" : action.status === "Failed" ? "\u2717" : "\u25CB";
|
|
6967
|
-
let line = `
|
|
7053
|
+
const status = action.status === "Succeeded" ? "\u2713" : action.status === "Failed" ? "\u2717" : action.status === "TimedOut" ? "\u23F1" : "\u25CB";
|
|
7054
|
+
let line = `
|
|
7055
|
+
${status} ${action.name} ${duration}`;
|
|
6968
7056
|
if (action.error) {
|
|
6969
|
-
line += `
|
|
7057
|
+
line += `
|
|
7058
|
+
Error: [${action.error.code}] ${action.error.message.slice(0, ERROR_TRUNCATE_LIMIT)}`;
|
|
7059
|
+
}
|
|
7060
|
+
if (action.inputs) {
|
|
7061
|
+
line += `
|
|
7062
|
+
Inputs: ${action.inputs}`;
|
|
7063
|
+
}
|
|
7064
|
+
if (action.outputs) {
|
|
7065
|
+
line += `
|
|
7066
|
+
Outputs: ${action.outputs}`;
|
|
7067
|
+
}
|
|
7068
|
+
if (action.trackedProperties && Object.keys(action.trackedProperties).length > 0) {
|
|
7069
|
+
line += `
|
|
7070
|
+
Tracked: ${JSON.stringify(action.trackedProperties)}`;
|
|
7071
|
+
}
|
|
7072
|
+
if (action.retryCount && action.retryCount > 0) {
|
|
7073
|
+
line += `
|
|
7074
|
+
Retries: ${action.retryCount}`;
|
|
7075
|
+
}
|
|
7076
|
+
lines.push(line);
|
|
7077
|
+
}
|
|
7078
|
+
return lines.join("\n");
|
|
7079
|
+
}
|
|
7080
|
+
var getRunActionRepetitionsInputSchema = z.object({
|
|
7081
|
+
flowId: z.string().describe("The flow ID (GUID)"),
|
|
7082
|
+
runId: z.string().describe("The run ID (GUID)"),
|
|
7083
|
+
actionName: z.string().describe("The exact action name inside the for_each/do_until loop"),
|
|
7084
|
+
environment: z.string().optional().describe("Environment name or GUID. Uses default if omitted."),
|
|
7085
|
+
failedOnly: z.boolean().optional().describe("If true, only return failed iterations (default: false)"),
|
|
7086
|
+
includeInputs: z.boolean().optional().describe("If true, fetch input data for each iteration (default: false)"),
|
|
7087
|
+
includeOutputs: z.boolean().optional().describe("If true, fetch output data for each iteration (default: true for failed)"),
|
|
7088
|
+
maxIterations: z.number().optional().describe("Maximum iterations to return (default: 50). Use to limit large loops.")
|
|
7089
|
+
});
|
|
7090
|
+
var getRunActionRepetitionsTool = {
|
|
7091
|
+
name: "get_run_action_repetitions",
|
|
7092
|
+
description: "Get iteration-level details for a for_each or do_until loop action in a flow run. Shows which iterations succeeded/failed, their inputs/outputs, and error details. Essential for debugging loops that partially fail.",
|
|
7093
|
+
inputSchema: {
|
|
7094
|
+
type: "object",
|
|
7095
|
+
properties: {
|
|
7096
|
+
flowId: {
|
|
7097
|
+
type: "string",
|
|
7098
|
+
description: "The flow ID (GUID)"
|
|
7099
|
+
},
|
|
7100
|
+
runId: {
|
|
7101
|
+
type: "string",
|
|
7102
|
+
description: "The run ID (GUID)"
|
|
7103
|
+
},
|
|
7104
|
+
actionName: {
|
|
7105
|
+
type: "string",
|
|
7106
|
+
description: "The exact action name inside the for_each/do_until loop"
|
|
7107
|
+
},
|
|
7108
|
+
environment: {
|
|
7109
|
+
type: "string",
|
|
7110
|
+
description: "Environment name or GUID. Uses default if omitted."
|
|
7111
|
+
},
|
|
7112
|
+
failedOnly: {
|
|
7113
|
+
type: "boolean",
|
|
7114
|
+
description: "If true, only return failed iterations (default: false)"
|
|
7115
|
+
},
|
|
7116
|
+
includeInputs: {
|
|
7117
|
+
type: "boolean",
|
|
7118
|
+
description: "If true, fetch input data for each iteration (default: false)"
|
|
7119
|
+
},
|
|
7120
|
+
includeOutputs: {
|
|
7121
|
+
type: "boolean",
|
|
7122
|
+
description: "If true, fetch output data for each iteration (default: true for failed)"
|
|
7123
|
+
},
|
|
7124
|
+
maxIterations: {
|
|
7125
|
+
type: "number",
|
|
7126
|
+
description: "Maximum iterations to return (default: 50). Use to limit large loops."
|
|
7127
|
+
}
|
|
7128
|
+
},
|
|
7129
|
+
required: ["flowId", "runId", "actionName"]
|
|
7130
|
+
}
|
|
7131
|
+
};
|
|
7132
|
+
var TRUNCATE_LIMIT2 = 1e3;
|
|
7133
|
+
function formatData(data) {
|
|
7134
|
+
if (data && typeof data === "object" && "body" in data) {
|
|
7135
|
+
const body = data.body;
|
|
7136
|
+
const str2 = typeof body === "object" ? JSON.stringify(body, null, 2) : String(body);
|
|
7137
|
+
return str2.length > TRUNCATE_LIMIT2 ? str2.slice(0, TRUNCATE_LIMIT2) + "\u2026" : str2;
|
|
7138
|
+
}
|
|
7139
|
+
const str = JSON.stringify(data, null, 2);
|
|
7140
|
+
return str.length > TRUNCATE_LIMIT2 ? str.slice(0, TRUNCATE_LIMIT2) + "\u2026" : str;
|
|
7141
|
+
}
|
|
7142
|
+
async function handleGetRunActionRepetitions(api, input) {
|
|
7143
|
+
const parsed = getRunActionRepetitionsInputSchema.parse(input);
|
|
7144
|
+
const maxIter = parsed.maxIterations ?? 50;
|
|
7145
|
+
logger.info({ input: parsed }, "Executing get_run_action_repetitions");
|
|
7146
|
+
const repetitions = await api.getFlowRunActionRepetitions(
|
|
7147
|
+
parsed.flowId,
|
|
7148
|
+
parsed.runId,
|
|
7149
|
+
parsed.actionName,
|
|
7150
|
+
parsed.environment
|
|
7151
|
+
);
|
|
7152
|
+
let filtered = repetitions;
|
|
7153
|
+
if (parsed.failedOnly) {
|
|
7154
|
+
filtered = filtered.filter(
|
|
7155
|
+
(r) => r.properties.status === "Failed" || r.properties.status === "TimedOut"
|
|
7156
|
+
);
|
|
7157
|
+
}
|
|
7158
|
+
const totalCount = filtered.length;
|
|
7159
|
+
filtered = filtered.slice(0, maxIter);
|
|
7160
|
+
const shouldFetchInputs = (status) => {
|
|
7161
|
+
if (parsed.includeInputs === true) return true;
|
|
7162
|
+
return false;
|
|
7163
|
+
};
|
|
7164
|
+
const shouldFetchOutputs = (status) => {
|
|
7165
|
+
if (parsed.includeOutputs === true) return true;
|
|
7166
|
+
if (parsed.includeOutputs === false) return false;
|
|
7167
|
+
return status === "Failed" || status === "TimedOut";
|
|
7168
|
+
};
|
|
7169
|
+
const iterIO = {};
|
|
7170
|
+
const fetchPromises = [];
|
|
7171
|
+
for (const rep of filtered) {
|
|
7172
|
+
const status = rep.properties.status;
|
|
7173
|
+
const key = rep.name;
|
|
7174
|
+
if (shouldFetchInputs() && rep.properties.inputsLink?.uri) {
|
|
7175
|
+
fetchPromises.push(
|
|
7176
|
+
api.fetchResourceLink(rep.properties.inputsLink.uri).then(
|
|
7177
|
+
(data) => {
|
|
7178
|
+
if (!iterIO[key]) iterIO[key] = {};
|
|
7179
|
+
iterIO[key].inputs = formatData(data);
|
|
7180
|
+
},
|
|
7181
|
+
(err) => {
|
|
7182
|
+
if (!iterIO[key]) iterIO[key] = {};
|
|
7183
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7184
|
+
iterIO[key].inputs = `(fetch error: ${msg.slice(0, 100)})`;
|
|
7185
|
+
}
|
|
7186
|
+
)
|
|
7187
|
+
);
|
|
7188
|
+
}
|
|
7189
|
+
if (shouldFetchOutputs(status) && rep.properties.outputsLink?.uri) {
|
|
7190
|
+
fetchPromises.push(
|
|
7191
|
+
api.fetchResourceLink(rep.properties.outputsLink.uri).then(
|
|
7192
|
+
(data) => {
|
|
7193
|
+
if (!iterIO[key]) iterIO[key] = {};
|
|
7194
|
+
iterIO[key].outputs = formatData(data);
|
|
7195
|
+
},
|
|
7196
|
+
(err) => {
|
|
7197
|
+
if (!iterIO[key]) iterIO[key] = {};
|
|
7198
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
7199
|
+
iterIO[key].outputs = `(fetch error: ${msg.slice(0, 100)})`;
|
|
7200
|
+
}
|
|
7201
|
+
)
|
|
7202
|
+
);
|
|
7203
|
+
}
|
|
7204
|
+
}
|
|
7205
|
+
await Promise.all(fetchPromises);
|
|
7206
|
+
const failedCount = filtered.filter(
|
|
7207
|
+
(r) => r.properties.status === "Failed" || r.properties.status === "TimedOut"
|
|
7208
|
+
).length;
|
|
7209
|
+
const succeededCount = filtered.filter(
|
|
7210
|
+
(r) => r.properties.status === "Succeeded"
|
|
7211
|
+
).length;
|
|
7212
|
+
const lines = [
|
|
7213
|
+
`Repetitions for "${parsed.actionName}": ${totalCount} total (${succeededCount} succeeded, ${failedCount} failed)`
|
|
7214
|
+
];
|
|
7215
|
+
if (totalCount > maxIter) {
|
|
7216
|
+
lines.push(` (showing first ${maxIter} of ${totalCount})`);
|
|
7217
|
+
}
|
|
7218
|
+
for (const rep of filtered) {
|
|
7219
|
+
const props = rep.properties;
|
|
7220
|
+
const startTime = new Date(props.startTime);
|
|
7221
|
+
const endTime = props.endTime ? new Date(props.endTime) : void 0;
|
|
7222
|
+
const durationMs = endTime ? endTime.getTime() - startTime.getTime() : void 0;
|
|
7223
|
+
const duration = durationMs ? `${(durationMs / 1e3).toFixed(1)}s` : "";
|
|
7224
|
+
const indexes = props.repetitionIndexes?.map((ri) => `${ri.scopeName}[${ri.itemIndex}]`).join(" > ");
|
|
7225
|
+
const status = props.status === "Succeeded" ? "\u2713" : props.status === "Failed" ? "\u2717" : props.status === "TimedOut" ? "\u23F1" : "\u25CB";
|
|
7226
|
+
let line = `
|
|
7227
|
+
${status} ${indexes ?? rep.name} ${duration}`;
|
|
7228
|
+
if (props.error) {
|
|
7229
|
+
line += `
|
|
7230
|
+
Error: [${props.error.code}] ${props.error.message.slice(0, 500)}`;
|
|
7231
|
+
}
|
|
7232
|
+
const io = iterIO[rep.name];
|
|
7233
|
+
if (io?.inputs) {
|
|
7234
|
+
line += `
|
|
7235
|
+
Inputs: ${io.inputs}`;
|
|
7236
|
+
}
|
|
7237
|
+
if (io?.outputs) {
|
|
7238
|
+
line += `
|
|
7239
|
+
Outputs: ${io.outputs}`;
|
|
6970
7240
|
}
|
|
6971
7241
|
lines.push(line);
|
|
6972
7242
|
}
|
|
@@ -12923,6 +13193,7 @@ var tools = [
|
|
|
12923
13193
|
// Phase 4: Connections, Diagnostics, Sharing
|
|
12924
13194
|
listConnectionsTool,
|
|
12925
13195
|
getRunActionsTool,
|
|
13196
|
+
getRunActionRepetitionsTool,
|
|
12926
13197
|
getFlowPermissionsTool,
|
|
12927
13198
|
shareFlowTool,
|
|
12928
13199
|
// Phase 5: Run Control, Environment Management
|
|
@@ -13058,6 +13329,9 @@ async function executeTool(context, toolName, input) {
|
|
|
13058
13329
|
case "get_run_actions":
|
|
13059
13330
|
result = await handleGetRunActions(context.flowApi, input);
|
|
13060
13331
|
break;
|
|
13332
|
+
case "get_run_action_repetitions":
|
|
13333
|
+
result = await handleGetRunActionRepetitions(context.flowApi, input);
|
|
13334
|
+
break;
|
|
13061
13335
|
case "get_flow_permissions":
|
|
13062
13336
|
result = await handleGetFlowPermissions(context.flowApi, input);
|
|
13063
13337
|
break;
|