answer42 0.2.29__tar.gz → 0.2.30__tar.gz
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.
- {answer42-0.2.29 → answer42-0.2.30}/PKG-INFO +1 -1
- {answer42-0.2.29 → answer42-0.2.30}/pyproject.toml +1 -1
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl +79 -6
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/server.py +5 -3
- {answer42-0.2.29 → answer42-0.2.30}/.gitignore +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/LICENSE +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/README.md +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/credentials.example.json +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/docs/agent-installation.md +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/docs/architecture.md +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/docs/assets/answer42-logo.png +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/docs/assets/platform42-logo.svg +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/docs/installation.md +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/scripts/build_cf.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/scripts/build_pages.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/scripts/e2e_stable.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/scripts/openclaw_mcp_autoreload.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/scripts/rag_cli.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/Configuration.xml +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Catalogs//320/237/320/241_/320/222/320/273/320/260/320/264/320/265/320/273/320/265/321/206.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Catalogs//320/237/320/241_/320/241/320/277/321/200/320/260/320/262/320/276/321/207/320/275/320/270/320/2721.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Configuration.xml +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Ext/ManagerModule.bsl" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Ext/ObjectModule.bsl" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Templates//320/236/321/201/320/275/320/276/320/262/320/275/320/260/321/217/320/241/321/205/320/265/320/274/320/260/320/232/320/276/320/274/320/277/320/276/320/275/320/276/320/262/320/272/320/270/320/224/320/260/320/275/320/275/321/213/321/205/Ext/Template.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262/Templates//320/236/321/201/320/275/320/276/320/262/320/275/320/260/321/217/320/241/321/205/320/265/320/274/320/260/320/232/320/276/320/274/320/277/320/276/320/275/320/276/320/262/320/272/320/270/320/224/320/260/320/275/320/275/321/213/321/205.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/client_cf/Reports//320/237/320/241_/320/241/320/277/320/270/321/201/320/276/320/272/320/255/320/273/320/265/320/274/320/265/320/275/321/202/320/276/320/262.xml" +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/__init__.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/assets/__init__.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/bridge.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/credentials.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/os_support.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/platform.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/protocol.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/rag/__init__.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/rag/detect.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/rag/model.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/rag/parsers.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/rag/service.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/rag/store.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/recorder.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/release_helper.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/runtime.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/skill_installer.py +0 -0
- {answer42-0.2.29 → answer42-0.2.30}/src/mcp_1c/window_control.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: answer42
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.30
|
|
4
4
|
Summary: Answer42 — The Answer to Life, Universe, and 1C — UI Driver. MCP-powered 1C:Enterprise UI automation: click, fill, navigate, test, and introspect managed forms through the test-client API
|
|
5
5
|
Author: Marvin (AI Assistant), 42Clouds, and contributors
|
|
6
6
|
Author-email: "Kosolapov Stanislav (proDOOMman)" <prodoomman@gmail.com>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "answer42"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.30"
|
|
4
4
|
description = "Answer42 — The Answer to Life, Universe, and 1C — UI Driver. MCP-powered 1C:Enterprise UI automation: click, fill, navigate, test, and introspect managed forms through the test-client API"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11"
|
|
@@ -3830,8 +3830,13 @@
|
|
|
3830
3830
|
КонецПопытки;
|
|
3831
3831
|
|
|
3832
3832
|
Если ТекстовыйВводВыполнен Тогда
|
|
3833
|
-
|
|
3834
|
-
|
|
3833
|
+
// Для полей выбора, особенно редакторов ячеек таблиц настроек, ВвестиТекст()
|
|
3834
|
+
// может не менять представление напрямую, но после этого остаются доступны
|
|
3835
|
+
// штатные методы выбора из списка/меню. Не отменяем редактирование сразу:
|
|
3836
|
+
// сначала пробуем choice/menu fallback-и ниже. Если они тоже не сработают,
|
|
3837
|
+
// финальный обработчик ошибок отменит редактирование ячейки через
|
|
3838
|
+
// ЗакончитьРедактированиеСтроки(Истина).
|
|
3839
|
+
Ошибки.Добавить("ВвестиТекст=выполнен, но значение не подтвердилось; текущее представление: " + НеподтвержденноеПредставлениеПослеВвода);
|
|
3835
3840
|
КонецЕсли;
|
|
3836
3841
|
|
|
3837
3842
|
// Переключатели/радиокнопки и поля со списком выбора: после активации
|
|
@@ -4259,9 +4264,76 @@
|
|
|
4259
4264
|
Возврат Новый Структура("found,name,title,added", Ложь, ИмяТаблицы, ЗаголовокТаблицы, Ложь);
|
|
4260
4265
|
КонецЕсли;
|
|
4261
4266
|
Таблица.Активизировать();
|
|
4262
|
-
|
|
4263
|
-
|
|
4264
|
-
|
|
4267
|
+
ТекущаяСтрокаДоJSON = "";
|
|
4268
|
+
Попытка
|
|
4269
|
+
ТекущаяСтрокаДоJSON = ЗначениеВJSON(СоответствиеВСтруктуру(Таблица.ПолучитьТекущуюСтроку()));
|
|
4270
|
+
Исключение
|
|
4271
|
+
ТекущаяСтрокаДоJSON = "";
|
|
4272
|
+
КонецПопытки;
|
|
4273
|
+
ОшибкаДобавленияСтроки = "";
|
|
4274
|
+
Попытка
|
|
4275
|
+
Таблица.ДобавитьСтроку();
|
|
4276
|
+
ТекущаяСтрока = Таблица.ПолучитьТекущуюСтроку();
|
|
4277
|
+
ТекущаяСтрокаПослеJSON = ЗначениеВJSON(СоответствиеВСтруктуру(ТекущаяСтрока));
|
|
4278
|
+
РежимРедактирования = ТаблицаВРежимеРедактированияMCP(Таблица);
|
|
4279
|
+
Если РежимРедактирования Или ТекущаяСтрокаДоJSON <> ТекущаяСтрокаПослеJSON Тогда
|
|
4280
|
+
Возврат Новый Структура("found,added,method,editing,current_row", Истина, Истина, "api_add_row", РежимРедактирования, СоответствиеВСтруктуру(ТекущаяСтрока));
|
|
4281
|
+
КонецЕсли;
|
|
4282
|
+
Исключение
|
|
4283
|
+
ОшибкаДобавленияСтроки = ОписаниеОшибки();
|
|
4284
|
+
КонецПопытки;
|
|
4285
|
+
|
|
4286
|
+
КнопкаДобавления = НайтиКнопкуДобавленияСтрокиТаблицыMCP(АктивноеОкно, Таблица, ИмяТаблицы, Глубина);
|
|
4287
|
+
Если КнопкаДобавления <> Неопределено Тогда
|
|
4288
|
+
ИмяКнопки = БезопасноеСвойство(КнопкаДобавления, "Имя", "");
|
|
4289
|
+
ЗаголовокКнопки = БезопасныйЗаголовок(КнопкаДобавления);
|
|
4290
|
+
КнопкаДобавления.Нажать();
|
|
4291
|
+
НовоеОкно = ТестируемоеПриложение.ПолучитьАктивноеОкно();
|
|
4292
|
+
МодальноеОкноОткрыто = НовоеОкно <> Неопределено И НовоеОкно <> АктивноеОкно;
|
|
4293
|
+
Возврат Новый Структура("found,added,method,button_name,button_title,modal_opened,modal_title,api_add_error", Истина, Истина, "command_button", ИмяКнопки, ЗаголовокКнопки, МодальноеОкноОткрыто, ?(МодальноеОкноОткрыто, БезопасноеСвойство(НовоеОкно, "Заголовок", ""), ""), ОшибкаДобавленияСтроки);
|
|
4294
|
+
КонецЕсли;
|
|
4295
|
+
Если Не ПустаяСтрока(ОшибкаДобавленияСтроки) Тогда
|
|
4296
|
+
ВызватьИсключение ОшибкаДобавленияСтроки;
|
|
4297
|
+
КонецЕсли;
|
|
4298
|
+
Возврат Новый Структура("found,added,method,editing,current_row", Истина, Ложь, "api_add_row_no_effect", ТаблицаВРежимеРедактированияMCP(Таблица), СоответствиеВСтруктуру(Таблица.ПолучитьТекущуюСтроку()));
|
|
4299
|
+
КонецФункции
|
|
4300
|
+
|
|
4301
|
+
&НаКлиенте
|
|
4302
|
+
Функция НайтиКнопкуДобавленияСтрокиТаблицыMCP(АктивноеОкно, Таблица, ИмяТаблицы, Глубина)
|
|
4303
|
+
Кандидаты = Новый Массив;
|
|
4304
|
+
Если Не ПустаяСтрока(ИмяТаблицы) Тогда
|
|
4305
|
+
Кандидаты.Добавить(ИмяТаблицы + "ДобавитьЭлементПорядка");
|
|
4306
|
+
Кандидаты.Добавить(ИмяТаблицы + "ДобавитьЭлемент");
|
|
4307
|
+
Кандидаты.Добавить(ИмяТаблицы + "ДобавитьСтроку");
|
|
4308
|
+
Кандидаты.Добавить(ИмяТаблицы + "Добавить");
|
|
4309
|
+
КонецЕсли;
|
|
4310
|
+
Кандидаты.Добавить("ДобавитьЭлементПорядка");
|
|
4311
|
+
Кандидаты.Добавить("Добавить новый элемент порядка");
|
|
4312
|
+
Кандидаты.Добавить("Добавить");
|
|
4313
|
+
|
|
4314
|
+
Для Каждого ИмяКнопки Из Кандидаты Цикл
|
|
4315
|
+
Попытка
|
|
4316
|
+
Кнопка = НайтиКнопку(Таблица, ИмяКнопки, "", 0, Глубина);
|
|
4317
|
+
Если Кнопка <> Неопределено Тогда
|
|
4318
|
+
Возврат Кнопка;
|
|
4319
|
+
КонецЕсли;
|
|
4320
|
+
Исключение
|
|
4321
|
+
КонецПопытки;
|
|
4322
|
+
КонецЦикла;
|
|
4323
|
+
|
|
4324
|
+
Если АктивноеОкно <> Неопределено Тогда
|
|
4325
|
+
Для Каждого ИмяКнопки Из Кандидаты Цикл
|
|
4326
|
+
Попытка
|
|
4327
|
+
Кнопка = НайтиКнопку(АктивноеОкно, ИмяКнопки, "", 0, Глубина);
|
|
4328
|
+
Если Кнопка <> Неопределено Тогда
|
|
4329
|
+
Возврат Кнопка;
|
|
4330
|
+
КонецЕсли;
|
|
4331
|
+
Исключение
|
|
4332
|
+
КонецПопытки;
|
|
4333
|
+
КонецЦикла;
|
|
4334
|
+
КонецЕсли;
|
|
4335
|
+
|
|
4336
|
+
Возврат Неопределено;
|
|
4265
4337
|
КонецФункции
|
|
4266
4338
|
|
|
4267
4339
|
&НаКлиенте
|
|
@@ -4593,9 +4665,10 @@
|
|
|
4593
4665
|
Значения = СтруктураИзJSONПараметраMCP(Параметры, "values");
|
|
4594
4666
|
ИмяТаблицы = СвойствоСтруктуры(Параметры, "table", "ДополнительнаяИнформация");
|
|
4595
4667
|
ИскатьПоЗаголовку = СвойствоСтруктуры(Параметры, "search_by_title", Ложь);
|
|
4668
|
+
МаксимальнаяГлубина = СвойствоСтруктуры(Параметры, "max_depth", 20);
|
|
4596
4669
|
Результаты = Новый Массив;
|
|
4597
4670
|
Для Каждого КЗ Из Значения Цикл
|
|
4598
|
-
ПараметрыПоля = Новый Структура("table,field,value,search_by_title", ИмяТаблицы, Строка(КЗ.Ключ), Строка(КЗ.Значение),
|
|
4671
|
+
ПараметрыПоля = Новый Структура("table,field,value,search_by_title,max_depth", ИмяТаблицы, Строка(КЗ.Ключ), Строка(КЗ.Значение), ИскатьПоЗаголовку, МаксимальнаяГлубина);
|
|
4599
4672
|
Результаты.Добавить(УстановитьПолеТаблицыMCP(ПараметрыПоля));
|
|
4600
4673
|
КонецЦикла;
|
|
4601
4674
|
Возврат Новый Структура("set,table,values,results", Истина, ИмяТаблицы, Значения, Результаты);
|
|
@@ -44,7 +44,7 @@ _RAG = RagService()
|
|
|
44
44
|
_RAG_ENABLED = os.getenv("ONEC_MCP_DISABLE_RAG", "").strip().lower() not in {"1", "true", "yes", "on"}
|
|
45
45
|
_CREDENTIAL_STORE_ENABLED = os.getenv("ONEC_MCP_DISABLE_CREDENTIAL_STORE", "").strip().lower() not in {"1", "true", "yes", "on"}
|
|
46
46
|
_DEV_TOOLS_ENABLED = os.getenv("ONEC_MCP_DEV_TOOLS", "").strip().lower() in {"1", "true", "yes", "on"}
|
|
47
|
-
DEFAULT_SESSION = "default"
|
|
47
|
+
DEFAULT_SESSION = os.getenv("ONEC_MCP_DEFAULT_SESSION", f"default-{os.getpid()}")
|
|
48
48
|
STATE_FILE = os_support.runtime_path("ONEC_MCP_SESSION_STATE", "sessions.json")
|
|
49
49
|
AUTORELOAD_PID_FILE = os_support.runtime_path("ONEC_MCP_AUTORELOAD_PID_FILE", "answer42-autoreload.pid")
|
|
50
50
|
AUTORELOAD_LOG_FILE = os_support.runtime_path("ONEC_MCP_AUTORELOAD_LOG_FILE", "answer42-autoreload.log")
|
|
@@ -3168,11 +3168,12 @@ async def command_bar(*,
|
|
|
3168
3168
|
async def click_button(
|
|
3169
3169
|
name: Annotated[str, "Button name or title text"],
|
|
3170
3170
|
search_by_title: Annotated[bool, "If true, match visible title instead of object name"] = False,
|
|
3171
|
+
max_depth: Annotated[int, "Maximum search depth"] = 8,
|
|
3171
3172
|
*,
|
|
3172
3173
|
session_id: Annotated[str, "Session id"] = DEFAULT_SESSION,
|
|
3173
3174
|
) -> Any:
|
|
3174
3175
|
"""Find a button in the active UI tree and press it."""
|
|
3175
|
-
return await _bridge_call_recorded(session_id, "click_button", {"name": name, "search_by_title": search_by_title})
|
|
3176
|
+
return await _bridge_call_recorded(session_id, "click_button", {"name": name, "search_by_title": search_by_title, "max_depth": max_depth})
|
|
3176
3177
|
|
|
3177
3178
|
|
|
3178
3179
|
@mcp.tool()
|
|
@@ -4132,11 +4133,12 @@ async def table_set_row_values(
|
|
|
4132
4133
|
table: Annotated[str, "Table technical name"],
|
|
4133
4134
|
values: Annotated[str, "JSON object mapping column names/titles to values"],
|
|
4134
4135
|
search_by_title: Annotated[bool, "If true, match visible title instead of object name"] = False,
|
|
4136
|
+
max_depth: Annotated[int, "Maximum UI search depth"] = 20,
|
|
4135
4137
|
*,
|
|
4136
4138
|
session_id: Annotated[str, "Session id"] = DEFAULT_SESSION,
|
|
4137
4139
|
) -> Any:
|
|
4138
4140
|
"""Set multiple fields in the current row of a form table and verify each value."""
|
|
4139
|
-
return await _bridge_call_recorded(session_id, "table_set_row_values", {"table": table, "values": values, "search_by_title": search_by_title})
|
|
4141
|
+
return await _bridge_call_recorded(session_id, "table_set_row_values", {"table": table, "values": values, "search_by_title": search_by_title, "max_depth": max_depth})
|
|
4140
4142
|
|
|
4141
4143
|
|
|
4142
4144
|
@mcp.tool()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{answer42-0.2.29 → answer42-0.2.30}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|