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 asset
main
Marcus Sanatan 2026-01-08 01:44:32 -04:00 committed by GitHub
parent ea55c443bf
commit a17df1e4c9
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 83 additions and 7 deletions

View File

@ -91,14 +91,28 @@ namespace MCPForUnity.Editor.Tools
try
{
var result = await CommandRegistry.InvokeCommandAsync(toolName, commandParams).ConfigureAwait(true);
invocationSuccessCount++;
bool callSucceeded = DetermineCallSucceeded(result);
if (callSucceeded)
{
invocationSuccessCount++;
}
else
{
invocationFailureCount++;
anyCommandFailed = true;
}
commandResults.Add(new
{
tool = toolName,
callSucceeded = true,
callSucceeded,
result
});
if (!callSucceeded && failFast)
{
break;
}
}
catch (Exception ex)
{
@ -134,6 +148,39 @@ namespace MCPForUnity.Editor.Tools
: 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)
{
if (source == null)

View File

@ -29,9 +29,11 @@ namespace MCPForUnity.Editor.Tools.GameObjects
// --- Try Instantiating Prefab First ---
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;
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}'");
}
}
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";
}
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);
if (prefabAsset != null)
@ -83,7 +112,7 @@ namespace MCPForUnity.Editor.Tools.GameObjects
}
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}'.");
}
}