feat(batch_execute): improve error handling with success detection and fail-fast support (#531)
- Add DetermineCallSucceeded() to check command success via IMcpResponse interface or JObject/JToken 'success' field - Track invocationFailureCount and set anyCommandFailed flag when commands fail - Implement fail-fast behavior to stop batch execution on first failure when failFast=true - Update commandResults to use computed callSucceeded value instead of hardcoded true feat(game_object_create): enhance assetmain
parent
ea55c443bf
commit
a17df1e4c9
|
|
@ -91,14 +91,28 @@ namespace MCPForUnity.Editor.Tools
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var result = await CommandRegistry.InvokeCommandAsync(toolName, commandParams).ConfigureAwait(true);
|
var result = await CommandRegistry.InvokeCommandAsync(toolName, commandParams).ConfigureAwait(true);
|
||||||
|
bool callSucceeded = DetermineCallSucceeded(result);
|
||||||
|
if (callSucceeded)
|
||||||
|
{
|
||||||
invocationSuccessCount++;
|
invocationSuccessCount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
invocationFailureCount++;
|
||||||
|
anyCommandFailed = true;
|
||||||
|
}
|
||||||
|
|
||||||
commandResults.Add(new
|
commandResults.Add(new
|
||||||
{
|
{
|
||||||
tool = toolName,
|
tool = toolName,
|
||||||
callSucceeded = true,
|
callSucceeded,
|
||||||
result
|
result
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (!callSucceeded && failFast)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -134,6 +148,39 @@ namespace MCPForUnity.Editor.Tools
|
||||||
: new ErrorResponse("One or more commands failed.", data);
|
: new ErrorResponse("One or more commands failed.", data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool DetermineCallSucceeded(object result)
|
||||||
|
{
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result is IMcpResponse response)
|
||||||
|
{
|
||||||
|
return response.Success;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result is JObject obj)
|
||||||
|
{
|
||||||
|
var successToken = obj["success"];
|
||||||
|
if (successToken != null && successToken.Type == JTokenType.Boolean)
|
||||||
|
{
|
||||||
|
return successToken.Value<bool>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result is JToken token)
|
||||||
|
{
|
||||||
|
var successToken = token["success"];
|
||||||
|
if (successToken != null && successToken.Type == JTokenType.Boolean)
|
||||||
|
{
|
||||||
|
return successToken.Value<bool>();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static JObject NormalizeParameterKeys(JObject source)
|
private static JObject NormalizeParameterKeys(JObject source)
|
||||||
{
|
{
|
||||||
if (source == null)
|
if (source == null)
|
||||||
|
|
|
||||||
|
|
@ -29,9 +29,11 @@ namespace MCPForUnity.Editor.Tools.GameObjects
|
||||||
|
|
||||||
// --- Try Instantiating Prefab First ---
|
// --- Try Instantiating Prefab First ---
|
||||||
string originalPrefabPath = prefabPath;
|
string originalPrefabPath = prefabPath;
|
||||||
if (!string.IsNullOrEmpty(prefabPath))
|
if (!saveAsPrefab && !string.IsNullOrEmpty(prefabPath))
|
||||||
{
|
{
|
||||||
if (!prefabPath.Contains("/") && !prefabPath.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
|
string extension = System.IO.Path.GetExtension(prefabPath);
|
||||||
|
|
||||||
|
if (!prefabPath.Contains("/") && (string.IsNullOrEmpty(extension) || extension.Equals(".prefab", StringComparison.OrdinalIgnoreCase)))
|
||||||
{
|
{
|
||||||
string prefabNameOnly = prefabPath;
|
string prefabNameOnly = prefabPath;
|
||||||
McpLog.Info($"[ManageGameObject.Create] Searching for prefab named: '{prefabNameOnly}'");
|
McpLog.Info($"[ManageGameObject.Create] Searching for prefab named: '{prefabNameOnly}'");
|
||||||
|
|
@ -51,11 +53,38 @@ namespace MCPForUnity.Editor.Tools.GameObjects
|
||||||
McpLog.Info($"[ManageGameObject.Create] Found unique prefab at path: '{prefabPath}'");
|
McpLog.Info($"[ManageGameObject.Create] Found unique prefab at path: '{prefabPath}'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!prefabPath.EndsWith(".prefab", StringComparison.OrdinalIgnoreCase))
|
else if (prefabPath.Contains("/") && string.IsNullOrEmpty(extension))
|
||||||
{
|
{
|
||||||
McpLog.Warn($"[ManageGameObject.Create] Provided prefabPath '{prefabPath}' does not end with .prefab. Assuming it's missing and appending.");
|
McpLog.Warn($"[ManageGameObject.Create] Provided prefabPath '{prefabPath}' has no extension. Assuming it's a prefab and appending .prefab.");
|
||||||
prefabPath += ".prefab";
|
prefabPath += ".prefab";
|
||||||
}
|
}
|
||||||
|
else if (!prefabPath.Contains("/") && !string.IsNullOrEmpty(extension) && !extension.Equals(".prefab", StringComparison.OrdinalIgnoreCase))
|
||||||
|
{
|
||||||
|
string fileName = prefabPath;
|
||||||
|
string fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(fileName);
|
||||||
|
McpLog.Info($"[ManageGameObject.Create] Searching for asset file named: '{fileName}'");
|
||||||
|
|
||||||
|
string[] guids = AssetDatabase.FindAssets(fileNameWithoutExtension);
|
||||||
|
var matches = guids
|
||||||
|
.Select(g => AssetDatabase.GUIDToAssetPath(g))
|
||||||
|
.Where(p => p.EndsWith("/" + fileName, StringComparison.OrdinalIgnoreCase) || p.Equals(fileName, StringComparison.OrdinalIgnoreCase))
|
||||||
|
.ToArray();
|
||||||
|
|
||||||
|
if (matches.Length == 0)
|
||||||
|
{
|
||||||
|
return new ErrorResponse($"Asset file '{fileName}' not found anywhere in the project.");
|
||||||
|
}
|
||||||
|
else if (matches.Length > 1)
|
||||||
|
{
|
||||||
|
string foundPaths = string.Join(", ", matches);
|
||||||
|
return new ErrorResponse($"Multiple assets found matching file name '{fileName}': {foundPaths}. Please provide a more specific path.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
prefabPath = matches[0];
|
||||||
|
McpLog.Info($"[ManageGameObject.Create] Found unique asset at path: '{prefabPath}'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GameObject prefabAsset = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
GameObject prefabAsset = AssetDatabase.LoadAssetAtPath<GameObject>(prefabPath);
|
||||||
if (prefabAsset != null)
|
if (prefabAsset != null)
|
||||||
|
|
@ -83,7 +112,7 @@ namespace MCPForUnity.Editor.Tools.GameObjects
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
McpLog.Warn($"[ManageGameObject.Create] Prefab asset not found at path: '{prefabPath}'. Will proceed to create new object if specified.");
|
return new ErrorResponse($"Asset not found or not a GameObject at path: '{prefabPath}'.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue