From a30614d0057c08334779436a6d39f75dc41f4357 Mon Sep 17 00:00:00 2001 From: Shahovalov MIkhail Date: Wed, 27 May 2026 11:20:38 +0300 Subject: [PATCH] =?UTF-8?q?fix:=20=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20?= =?UTF-8?q?=D0=BF=D0=B0=D1=80=D0=B0=D0=BC=D0=B5=D1=82=D1=80=D0=B8=D0=BA?= =?UTF-8?q?=D0=B8=20=D0=BF=D0=BE=20=D1=80=D0=B5=D0=B2=D1=8C=D1=8E=20Codex?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - проверка возврата ksPart.RebuildModel() во всех операциях (не рапортовать успех при неудаче) — P2 - сообщение об удалении: намёк на зависимые переменные — P3 - дисклеймер про геометрию в описании set_variable + десятичный разделитель — P3 - тест дополнен: дубликат имени, удаление с зависимыми, десятичное выражение (3.5), пересчёт зависимой - 116 тестов зелёных --- src/Kompas.Mcp.Core/Modeling/VariableService.cs | 13 +++++++++---- src/Kompas.Mcp.Host/Tools/VariableTools.cs | 2 +- tests/Kompas.Mcp.Tests/Integration/VariableTests.cs | 10 ++++++++++ 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/Kompas.Mcp.Core/Modeling/VariableService.cs b/src/Kompas.Mcp.Core/Modeling/VariableService.cs index f810177..02aa2a4 100644 --- a/src/Kompas.Mcp.Core/Modeling/VariableService.cs +++ b/src/Kompas.Mcp.Core/Modeling/VariableService.cs @@ -38,7 +38,8 @@ public sealed class VariableService var v = vc.AddNewVariable(name, value, note ?? "") as ksVariable ?? throw new InvalidOperationException("AddNewVariable вернул null (недопустимое имя?)."); if (external) v.external = true; - part.RebuildModel(); + if (!part.RebuildModel()) + throw new InvalidOperationException($"Не удалось применить создание переменной '{name}' (RebuildModel вернул FALSE)."); return ReadValueFresh(name); // значение перечитываем после перестроения }, ct); @@ -53,7 +54,9 @@ public sealed class VariableService var (part, vc) = RootVariables(); var v = RequireVariable(vc, name); v.Expression = expression; - part.RebuildModel(); + if (!part.RebuildModel()) + throw new InvalidOperationException( + $"Не удалось пересчитать модель с выражением «{expression}» для '{name}' (недопустимое выражение или ссылка на несуществующую переменную?)."); return ReadValueFresh(name); // переменную перечитываем после перестроения (value пересчитан) }, ct); @@ -65,8 +68,10 @@ public sealed class VariableService var (part, vc) = RootVariables(); RequireVariable(vc, name); // понятная ошибка, если её нет if (!vc.RemoveVariable(name)) - throw new InvalidOperationException($"Не удалось удалить переменную '{name}'."); - part.RebuildModel(); + throw new InvalidOperationException( + $"Не удалось удалить переменную '{name}' (возможно, на неё ссылаются другие переменные — удалите зависимые сначала)."); + if (!part.RebuildModel()) + throw new InvalidOperationException($"Не удалось применить удаление переменной '{name}' (RebuildModel вернул FALSE)."); }, ct); /// Прочитать текущее (вычисленное) значение переменной. diff --git a/src/Kompas.Mcp.Host/Tools/VariableTools.cs b/src/Kompas.Mcp.Host/Tools/VariableTools.cs index 7f89f2e..56b433e 100644 --- a/src/Kompas.Mcp.Host/Tools/VariableTools.cs +++ b/src/Kompas.Mcp.Host/Tools/VariableTools.cs @@ -23,7 +23,7 @@ public sealed class VariableTools(KompasSession session, VariableService variabl } [McpServerTool(Name = "set_variable")] - [Description("Задать выражение существующей переменной: константа (например «30») или формула со ссылками на другие переменные (например «width*2+5»). Модель перестраивается, значение пересчитывается. Возвращает вычисленное значение.")] + [Description("Задать выражение существующей переменной: константа (например «30») или формула со ссылками на другие переменные (например «width*2+5»). Модель перестраивается, значение пересчитывается. Десятичный разделитель — точка. Примечание: изменит геометрию только в параметрической модели (где размеры эскизов связаны с именами переменных); для моделей с литеральными размерами значение пересчитается, но геометрия не изменится. Возвращает вычисленное значение.")] public async Task SetVariable( string name, [Description("Выражение: число или формула (width*2+5)")] string expression) diff --git a/tests/Kompas.Mcp.Tests/Integration/VariableTests.cs b/tests/Kompas.Mcp.Tests/Integration/VariableTests.cs index bff3b3f..3e192dc 100644 --- a/tests/Kompas.Mcp.Tests/Integration/VariableTests.cs +++ b/tests/Kompas.Mcp.Tests/Integration/VariableTests.cs @@ -48,11 +48,21 @@ public sealed class VariableTests Assert.Equal(20, computed, 3); Assert.Equal(20, await _vars.GetVariableValueAsync("width"), 3); + // дубликат имени отвергается + await Assert.ThrowsAsync(() => _vars.CreateVariableAsync("width", 1)); + // вторая переменная, ссылающаяся на первую (формула с именем переменной) await _vars.CreateVariableAsync("height", 5); var doubled = await _vars.SetVariableAsync("height", "width * 2"); Assert.Equal(40, doubled, 3); // width=20 → 40 + // десятичный разделитель — точка; зависимая переменная пересчитывается + Assert.Equal(3.5, await _vars.SetVariableAsync("width", "3.5"), 3); + Assert.Equal(7, await _vars.GetVariableValueAsync("height"), 3); // 3.5*2 + + // нельзя удалить переменную, на которую ссылаются (height = width*2) + await Assert.ThrowsAsync(() => _vars.DeleteVariableAsync("width")); + // delete (в порядке зависимостей: сначала зависимая height, затем width) await _vars.DeleteVariableAsync("height"); await _vars.DeleteVariableAsync("width");