answer42 0.4.63__tar.gz → 0.4.64__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.4.63 → answer42-0.4.64}/PKG-INFO +1 -1
- {answer42-0.4.63 → answer42-0.4.64}/pyproject.toml +1 -1
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl +123 -20
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/server.py +37 -17
- {answer42-0.4.63 → answer42-0.4.64}/.gitignore +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/LICENSE +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/README.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/credentials.example.json +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/docs/agent-installation.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/docs/architecture.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/docs/assets/answer42-logo.png +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/docs/assets/platform42-logo.svg +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/docs/installation.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/scripts/build_cf.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/scripts/build_pages.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/scripts/e2e_http_smoke.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/scripts/e2e_stable.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/scripts/openclaw_mcp_autoreload.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/scripts/rag_cli.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/Configuration.xml +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/src/client_cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/client_cf/Configuration.xml +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/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.4.63 → answer42-0.4.64}/src/mcp_1c/__init__.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/__init__.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/skills/answer42-universal-report/SKILL.md +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/auth.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/bridge.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/credentials.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/os_support.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/platform.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/protocol.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/__init__.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/detect.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/dump.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/model.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/parsers.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/service.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/store.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/summary_backend.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/rag/summary_vector.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/recorder.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/release_helper.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/runtime.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/skill_installer.py +0 -0
- {answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/window_control.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: answer42
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.64
|
|
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.4.
|
|
3
|
+
version = "0.4.64"
|
|
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"
|
|
@@ -1890,10 +1890,10 @@
|
|
|
1890
1890
|
АктивноеОкно = КомандныйИнтерфейсЦелевоеОкно(Параметры);
|
|
1891
1891
|
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
1892
1892
|
Если Интерфейс = Неопределено Тогда
|
|
1893
|
-
РезультатКоманды = Новый Структура("available,reason,window", Ложь, "not_available",
|
|
1893
|
+
РезультатКоманды = Новый Структура("available,reason,window", Ложь, "not_available", КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1894
1894
|
Иначе
|
|
1895
1895
|
Дерево = КомандныйИнтерфейсОбъектВСтруктуру(Интерфейс, 0);
|
|
1896
|
-
РезультатКоманды = Новый Структура("available,interface,window", Истина, Дерево,
|
|
1896
|
+
РезультатКоманды = Новый Структура("available,interface,window", Истина, Дерево, КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1897
1897
|
КонецЕсли;
|
|
1898
1898
|
ЗакрытьКомандныйИнтерфейсПослеРаботыMCP(АктивноеОкно);
|
|
1899
1899
|
Возврат РезультатКоманды;
|
|
@@ -1912,10 +1912,10 @@
|
|
|
1912
1912
|
АктивноеОкно = КомандныйИнтерфейсЦелевоеОкно(Параметры);
|
|
1913
1913
|
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
1914
1914
|
Если Интерфейс = Неопределено Тогда
|
|
1915
|
-
РезультатКоманды = Новый Структура("available,reason,window", Ложь, "not_available",
|
|
1915
|
+
РезультатКоманды = Новый Структура("available,reason,window", Ложь, "not_available", КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1916
1916
|
Иначе
|
|
1917
1917
|
Разделы = РазделыКомандногоИнтерфейса(Интерфейс);
|
|
1918
|
-
РезультатКоманды = Новый Структура("available,sections,window", Истина, Разделы,
|
|
1918
|
+
РезультатКоманды = Новый Структура("available,sections,window", Истина, Разделы, КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1919
1919
|
КонецЕсли;
|
|
1920
1920
|
ЗакрытьКомандныйИнтерфейсПослеРаботыMCP(АктивноеОкно);
|
|
1921
1921
|
Возврат РезультатКоманды;
|
|
@@ -1937,25 +1937,25 @@
|
|
|
1937
1937
|
АктивноеОкно = КомандныйИнтерфейсЦелевоеОкно(Параметры);
|
|
1938
1938
|
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
1939
1939
|
Если Интерфейс = Неопределено Тогда
|
|
1940
|
-
РезультатКоманды = Новый Структура("available,reason,window", Ложь, "not_available",
|
|
1940
|
+
РезультатКоманды = Новый Структура("available,reason,window", Ложь, "not_available", КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1941
1941
|
Иначе
|
|
1942
1942
|
Корень = Интерфейс;
|
|
1943
1943
|
Если Не ПустаяСтрока(ЗаголовокРаздела) Тогда
|
|
1944
1944
|
КнопкаРаздела = КомандныйИнтерфейсНайтиРаздел(Интерфейс, ЗаголовокРаздела);
|
|
1945
1945
|
Если КнопкаРаздела = Неопределено Тогда
|
|
1946
|
-
РезультатКоманды = Новый Структура("available,found,reason,section,window", Истина, Ложь, "section_not_found", ЗаголовокРаздела,
|
|
1946
|
+
РезультатКоманды = Новый Структура("available,found,reason,section,window", Истина, Ложь, "section_not_found", ЗаголовокРаздела, КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1947
1947
|
Иначе
|
|
1948
1948
|
КнопкаРаздела.Нажать();
|
|
1949
1949
|
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
1950
1950
|
Корень = Интерфейс;
|
|
1951
1951
|
Дерево = КомандныйИнтерфейсОбъектВСтруктуру(Корень, 0);
|
|
1952
1952
|
ЛокКоманды = КомандыКомандногоИнтерфейса(Корень, Истина);
|
|
1953
|
-
РезультатКоманды = Новый Структура("available,found,section,tree,commands,window", Истина, Истина, ЗаголовокРаздела, Дерево, ЛокКоманды,
|
|
1953
|
+
РезультатКоманды = Новый Структура("available,found,section,tree,commands,window", Истина, Истина, ЗаголовокРаздела, Дерево, ЛокКоманды, КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1954
1954
|
КонецЕсли;
|
|
1955
1955
|
Иначе
|
|
1956
1956
|
Дерево = КомандныйИнтерфейсОбъектВСтруктуру(Корень, 0);
|
|
1957
1957
|
ЛокКоманды = КомандыКомандногоИнтерфейса(Корень, Истина);
|
|
1958
|
-
РезультатКоманды = Новый Структура("available,found,section,tree,commands,window", Истина, Истина, ЗаголовокРаздела, Дерево, ЛокКоманды,
|
|
1958
|
+
РезультатКоманды = Новый Структура("available,found,section,tree,commands,window", Истина, Истина, ЗаголовокРаздела, Дерево, ЛокКоманды, КраткоеОписаниеОбъектаMCP(АктивноеОкно));
|
|
1959
1959
|
КонецЕсли;
|
|
1960
1960
|
КонецЕсли;
|
|
1961
1961
|
ЗакрытьКомандныйИнтерфейсПослеРаботыMCP(АктивноеОкно, КнопкаРаздела);
|
|
@@ -1974,6 +1974,8 @@
|
|
|
1974
1974
|
ВызватьИсключение "Тестируемое приложение не подключено.";
|
|
1975
1975
|
КонецЕсли;
|
|
1976
1976
|
|
|
1977
|
+
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1978
|
+
Тайминги = Новый Структура;
|
|
1977
1979
|
АктивноеОкно = Неопределено;
|
|
1978
1980
|
КнопкаРаздела = Неопределено;
|
|
1979
1981
|
Попытка
|
|
@@ -1984,35 +1986,70 @@
|
|
|
1984
1986
|
|
|
1985
1987
|
ЗаголовокРаздела = СвойствоСтруктуры(Параметры, "section", "");
|
|
1986
1988
|
Максимум = СвойствоСтруктуры(Параметры, "max_results", 20);
|
|
1989
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1987
1990
|
АктивноеОкно = КомандныйИнтерфейсЦелевоеОкно(Параметры);
|
|
1991
|
+
Тайминги.Вставить("target_window_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
1992
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1988
1993
|
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
1994
|
+
Тайминги.Вставить("get_interface_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
1989
1995
|
Если Интерфейс = Неопределено Тогда
|
|
1990
|
-
|
|
1996
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1997
|
+
ОписаниеОкна = КраткоеОписаниеОбъектаMCP(АктивноеОкно);
|
|
1998
|
+
Тайминги.Вставить("window_summary_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
1999
|
+
РезультатПоиска = Новый Структура("available,reason,window", Ложь, "not_available", ОписаниеОкна);
|
|
1991
2000
|
Иначе
|
|
1992
2001
|
Если Не ПустаяСтрока(ЗаголовокРаздела) Тогда
|
|
2002
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1993
2003
|
КнопкаРаздела = КомандныйИнтерфейсНайтиРаздел(Интерфейс, ЗаголовокРаздела);
|
|
2004
|
+
Тайминги.Вставить("find_section_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
1994
2005
|
Если КнопкаРаздела = Неопределено Тогда
|
|
1995
|
-
|
|
2006
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2007
|
+
ОписаниеОкна = КраткоеОписаниеОбъектаMCP(АктивноеОкно);
|
|
2008
|
+
Тайминги.Вставить("window_summary_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2009
|
+
РезультатПоиска = Новый Структура("available,found,reason,query,section,matches,window", Истина, Ложь, "section_not_found", СтрокаПоиска, ЗаголовокРаздела, Новый Массив, ОписаниеОкна);
|
|
1996
2010
|
Иначе
|
|
2011
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1997
2012
|
КнопкаРаздела.Нажать();
|
|
1998
2013
|
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
2014
|
+
Тайминги.Вставить("activate_section_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2015
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
1999
2016
|
ВсеКоманды = КомандыКомандногоИнтерфейса(Интерфейс, Истина);
|
|
2017
|
+
Тайминги.Вставить("collect_commands_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2018
|
+
Тайминги.Вставить("commands_count", ВсеКоманды.Количество());
|
|
2019
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2000
2020
|
Совпадения = ПоискВКомандахКомандногоИнтерфейса(ВсеКоманды, СтрокаПоиска, Максимум);
|
|
2001
|
-
|
|
2021
|
+
Тайминги.Вставить("match_commands_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2022
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2023
|
+
ОписаниеОкна = КраткоеОписаниеОбъектаMCP(АктивноеОкно);
|
|
2024
|
+
Тайминги.Вставить("window_summary_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2025
|
+
РезультатПоиска = Новый Структура("available,found,query,section,count,matches,window", Истина, Совпадения.Количество() > 0, СтрокаПоиска, ЗаголовокРаздела, Совпадения.Количество(), Совпадения, ОписаниеОкна);
|
|
2002
2026
|
КонецЕсли;
|
|
2003
2027
|
Иначе
|
|
2004
|
-
|
|
2028
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2029
|
+
ВсеКоманды = КомандыВсехРазделовКомандногоИнтерфейса(АктивноеОкно, Интерфейс, СтрокаПоиска, Максимум, Тайминги);
|
|
2030
|
+
Тайминги.Вставить("collect_commands_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2031
|
+
Тайминги.Вставить("commands_count", ВсеКоманды.Количество());
|
|
2032
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2005
2033
|
Совпадения = ПоискВКомандахКомандногоИнтерфейса(ВсеКоманды, СтрокаПоиска, Максимум);
|
|
2006
|
-
|
|
2034
|
+
Тайминги.Вставить("match_commands_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2035
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2036
|
+
ОписаниеОкна = КраткоеОписаниеОбъектаMCP(АктивноеОкно);
|
|
2037
|
+
Тайминги.Вставить("window_summary_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2038
|
+
РезультатПоиска = Новый Структура("available,found,query,section,count,matches,window", Истина, Совпадения.Количество() > 0, СтрокаПоиска, ЗаголовокРаздела, Совпадения.Количество(), Совпадения, ОписаниеОкна);
|
|
2007
2039
|
КонецЕсли;
|
|
2008
2040
|
КонецЕсли;
|
|
2041
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2009
2042
|
ЗакрытьКомандныйИнтерфейсПослеРаботыMCP(АктивноеОкно, КнопкаРаздела);
|
|
2043
|
+
Тайминги.Вставить("cleanup_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2044
|
+
Тайминги.Вставить("total_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало);
|
|
2045
|
+
РезультатПоиска.Вставить("_timings", Тайминги);
|
|
2010
2046
|
Возврат РезультатПоиска;
|
|
2011
2047
|
Исключение
|
|
2012
2048
|
Если АктивноеОкно <> Неопределено Тогда
|
|
2013
2049
|
ЗакрытьКомандныйИнтерфейсПослеРаботыMCP(АктивноеОкно, КнопкаРаздела);
|
|
2014
2050
|
КонецЕсли;
|
|
2015
|
-
|
|
2051
|
+
Тайминги.Вставить("total_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало);
|
|
2052
|
+
Возврат Новый Структура("available,reason,error,_timings", Ложь, "not_supported", ОписаниеОшибки(), Тайминги);
|
|
2016
2053
|
КонецПопытки;
|
|
2017
2054
|
КонецФункции
|
|
2018
2055
|
|
|
@@ -2187,6 +2224,39 @@
|
|
|
2187
2224
|
Возврат Результат;
|
|
2188
2225
|
КонецФункции
|
|
2189
2226
|
|
|
2227
|
+
&НаКлиенте
|
|
2228
|
+
Функция КомандыВсехРазделовКомандногоИнтерфейса(АктивноеОкно, Интерфейс, СтрокаПоиска, Максимум, Тайминги)
|
|
2229
|
+
Результат = Новый Массив;
|
|
2230
|
+
ПросмотреноРазделов = 0;
|
|
2231
|
+
Разделы = РазделыКомандногоИнтерфейса(Интерфейс);
|
|
2232
|
+
Тайминги.Вставить("sections_count", Разделы.Количество());
|
|
2233
|
+
Для Каждого Раздел Из Разделы Цикл
|
|
2234
|
+
ЗаголовокРаздела = СвойствоСтруктуры(Раздел, "title", "");
|
|
2235
|
+
Если ПустаяСтрока(ЗаголовокРаздела) Тогда
|
|
2236
|
+
Продолжить;
|
|
2237
|
+
КонецЕсли;
|
|
2238
|
+
КнопкаРаздела = КомандныйИнтерфейсНайтиРаздел(Интерфейс, ЗаголовокРаздела);
|
|
2239
|
+
Если КнопкаРаздела = Неопределено Тогда
|
|
2240
|
+
Продолжить;
|
|
2241
|
+
КонецЕсли;
|
|
2242
|
+
Попытка
|
|
2243
|
+
КнопкаРаздела.Нажать();
|
|
2244
|
+
Интерфейс = АктивноеОкно.ПолучитьКомандныйИнтерфейс();
|
|
2245
|
+
ПросмотреноРазделов = ПросмотреноРазделов + 1;
|
|
2246
|
+
КомандыРаздела = КомандыКомандногоИнтерфейса(Интерфейс, Истина);
|
|
2247
|
+
Для Каждого Команда Из КомандыРаздела Цикл
|
|
2248
|
+
Команда.Вставить("section", ЗаголовокРаздела);
|
|
2249
|
+
Результат.Добавить(Команда);
|
|
2250
|
+
КонецЦикла;
|
|
2251
|
+
Исключение
|
|
2252
|
+
// Отдельный раздел командного интерфейса может быть недоступен в текущем состоянии UI.
|
|
2253
|
+
КонецПопытки;
|
|
2254
|
+
КонецЦикла;
|
|
2255
|
+
Тайминги.Вставить("sections_scanned", ПросмотреноРазделов);
|
|
2256
|
+
Возврат Результат;
|
|
2257
|
+
КонецФункции
|
|
2258
|
+
|
|
2259
|
+
|
|
2190
2260
|
&НаКлиенте
|
|
2191
2261
|
Процедура КомандыКомандногоИнтерфейсаРекурсивно(Объект, Результат, Путь, ИсключатьСлужебныеПанели)
|
|
2192
2262
|
Если Объект = Неопределено Тогда
|
|
@@ -2250,10 +2320,18 @@
|
|
|
2250
2320
|
Совпадение.Вставить("navigation_url", Ссылка);
|
|
2251
2321
|
Совпадение.Вставить("path", Путь);
|
|
2252
2322
|
Совпадение.Вставить("path_text", ТекстПути);
|
|
2253
|
-
|
|
2254
|
-
|
|
2255
|
-
|
|
2256
|
-
|
|
2323
|
+
Оценка = КомандныйИнтерфейсОценкаСовпадения(Заголовок, ТекстПути, Ссылка, НормПоиск);
|
|
2324
|
+
Совпадение.Вставить("score", Оценка);
|
|
2325
|
+
ИндексВставки = Результат.Количество();
|
|
2326
|
+
Для НомерСовпадения = 0 По Результат.Количество() - 1 Цикл
|
|
2327
|
+
Если СвойствоСтруктуры(Результат[НомерСовпадения], "score", 0) < Оценка Тогда
|
|
2328
|
+
ИндексВставки = НомерСовпадения;
|
|
2329
|
+
Прервать;
|
|
2330
|
+
КонецЕсли;
|
|
2331
|
+
КонецЦикла;
|
|
2332
|
+
Результат.Вставить(ИндексВставки, Совпадение);
|
|
2333
|
+
Если Максимум > 0 И Результат.Количество() > Максимум Тогда
|
|
2334
|
+
Результат.Удалить(Результат.Количество() - 1);
|
|
2257
2335
|
КонецЕсли;
|
|
2258
2336
|
КонецЕсли;
|
|
2259
2337
|
КонецЦикла;
|
|
@@ -2899,19 +2977,44 @@
|
|
|
2899
2977
|
Возврат СтрНайти(Поиск, "команднаяпанель") > 0;
|
|
2900
2978
|
КонецФункции
|
|
2901
2979
|
|
|
2980
|
+
&НаКлиенте
|
|
2981
|
+
Функция КраткоеОписаниеОбъектаMCP(Объект)
|
|
2982
|
+
// Для диагностических полей window/object не сериализуем всё дерево формы:
|
|
2983
|
+
// на больших стартовых страницах БП полная ОбъектВСтруктуру() занимает десятки секунд.
|
|
2984
|
+
Возврат ОбъектВСтруктуру(Объект, 0, Истина, Истина, Истина, Ложь, Неопределено, Ложь, Ложь, Неопределено, Ложь);
|
|
2985
|
+
КонецФункции
|
|
2986
|
+
|
|
2902
2987
|
&НаКлиенте
|
|
2903
2988
|
Функция КоманднаяПанель()
|
|
2904
2989
|
Если ТестируемоеПриложение = Неопределено Тогда
|
|
2905
2990
|
ВызватьИсключение "Тестируемое приложение не подключено.";
|
|
2906
2991
|
КонецЕсли;
|
|
2992
|
+
Начало = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2993
|
+
Тайминги = Новый Структура;
|
|
2994
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2907
2995
|
АктивноеОкно = ТестируемоеПриложение.ПолучитьАктивноеОкно();
|
|
2996
|
+
Тайминги.Вставить("active_window_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
2908
2997
|
Попытка
|
|
2998
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
2909
2999
|
Панель = АктивноеОкно.ПолучитьКоманднуюПанель();
|
|
2910
|
-
|
|
3000
|
+
Тайминги.Вставить("get_command_panel_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
3001
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
3002
|
+
Результат = ОбъектВСтруктуру(Панель, 0);
|
|
3003
|
+
Тайминги.Вставить("serialize_panel_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
3004
|
+
Тайминги.Вставить("total_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало);
|
|
3005
|
+
Если Результат <> Неопределено И Результат <> "__skip__" Тогда
|
|
3006
|
+
Результат.Вставить("_timings", Тайминги);
|
|
3007
|
+
КонецЕсли;
|
|
3008
|
+
Возврат Результат;
|
|
2911
3009
|
Исключение
|
|
2912
3010
|
// Не все объекты API тест-клиента поддерживают ПолучитьКоманднуюПанель.
|
|
2913
3011
|
// Возвращаем диагностику окна вместо пользовательской ошибки.
|
|
2914
|
-
|
|
3012
|
+
Тайминги.Вставить("error_before_window_serialize_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало);
|
|
3013
|
+
НачалоЭтапа = ТекущаяУниверсальнаяДатаВМиллисекундах();
|
|
3014
|
+
ОписаниеОкна = КраткоеОписаниеОбъектаMCP(АктивноеОкно);
|
|
3015
|
+
Тайминги.Вставить("serialize_window_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - НачалоЭтапа);
|
|
3016
|
+
Тайминги.Вставить("total_ms", ТекущаяУниверсальнаяДатаВМиллисекундах() - Начало);
|
|
3017
|
+
Возврат Новый Структура("available,reason,window,_timings", Ложь, "not_supported", ОписаниеОкна, Тайминги);
|
|
2915
3018
|
КонецПопытки;
|
|
2916
3019
|
КонецФункции
|
|
2917
3020
|
|
|
@@ -2897,6 +2897,15 @@ def _rag_fields_for_object(object_full_name: str, snapshot: str | int | None = N
|
|
|
2897
2897
|
return list(dedup.values())
|
|
2898
2898
|
|
|
2899
2899
|
|
|
2900
|
+
|
|
2901
|
+
|
|
2902
|
+
def _strip_bridge_timings(result: Any) -> Any:
|
|
2903
|
+
if not isinstance(result, dict) or "_timings" not in result:
|
|
2904
|
+
return result
|
|
2905
|
+
cleaned = dict(result)
|
|
2906
|
+
cleaned.pop("_timings", None)
|
|
2907
|
+
return cleaned
|
|
2908
|
+
|
|
2900
2909
|
async def _bridge_call_recorded(
|
|
2901
2910
|
session_id: str,
|
|
2902
2911
|
method: str,
|
|
@@ -5557,15 +5566,17 @@ async def command_interface_search(
|
|
|
5557
5566
|
section: Annotated[str, "Optional top-level section title substring to activate before searching"] = "",
|
|
5558
5567
|
max_results: Annotated[int, "Maximum number of matches to return; 0 means no limit"] = 20,
|
|
5559
5568
|
window_title: Annotated[str, "Optional window title substring to activate before reading command interface"] = "",
|
|
5569
|
+
include_timings: Annotated[bool, "Include diagnostic timing breakdown in the returned _timings field"] = False,
|
|
5560
5570
|
*,
|
|
5561
5571
|
session_id: Annotated[str, "Session id"] = DEFAULT_SESSION,
|
|
5562
5572
|
) -> Any:
|
|
5563
5573
|
"""Search live command-interface commands by title, path or navigation URL."""
|
|
5564
|
-
|
|
5574
|
+
result = await _bridge_call_recorded(
|
|
5565
5575
|
session_id,
|
|
5566
5576
|
"command_interface_search",
|
|
5567
5577
|
{"query": query, "section": section, "max_results": max_results, "window_title": window_title},
|
|
5568
5578
|
)
|
|
5579
|
+
return result if include_timings else _strip_bridge_timings(result)
|
|
5569
5580
|
|
|
5570
5581
|
|
|
5571
5582
|
@mcp.tool()
|
|
@@ -6084,7 +6095,9 @@ async def ui_tree_resource_action(
|
|
|
6084
6095
|
raise ValueError(f"Unsupported ui_tree_resource_action action: {action!r}. Expected focus, click_button, activate_field, field_value_text, or field_info.")
|
|
6085
6096
|
|
|
6086
6097
|
@mcp.tool()
|
|
6087
|
-
async def command_bar(
|
|
6098
|
+
async def command_bar(
|
|
6099
|
+
include_timings: Annotated[bool, "Include diagnostic timing breakdown in the returned _timings field"] = False,
|
|
6100
|
+
*,
|
|
6088
6101
|
session_id: Annotated[str, "Session id"] = DEFAULT_SESSION,
|
|
6089
6102
|
) -> Any:
|
|
6090
6103
|
"""Low-level diagnostic: return active window/form command-bar data when available.
|
|
@@ -6092,7 +6105,8 @@ async def command_bar(*,
|
|
|
6092
6105
|
Prefer command_interface_sections/commands/search for application navigation commands,
|
|
6093
6106
|
and object_command_panel/object_context_menu for commands of a specific UI object.
|
|
6094
6107
|
"""
|
|
6095
|
-
|
|
6108
|
+
result = await _bridge_call_recorded(session_id, "command_bar", {})
|
|
6109
|
+
return result if include_timings else _strip_bridge_timings(result)
|
|
6096
6110
|
|
|
6097
6111
|
|
|
6098
6112
|
|
|
@@ -8412,34 +8426,40 @@ async def configuration_name_version_from_subsystems(
|
|
|
8412
8426
|
warnings: list[str] = []
|
|
8413
8427
|
main: dict[str, str] = {}
|
|
8414
8428
|
cells: list[list[str]] = []
|
|
8415
|
-
source_method = "
|
|
8429
|
+
source_method = "sorted_edge_row"
|
|
8416
8430
|
current_row: dict[str, str] = {}
|
|
8417
8431
|
sort_attempts: list[dict[str, Any]] = []
|
|
8418
8432
|
|
|
8419
|
-
|
|
8420
|
-
|
|
8433
|
+
sort_result = await _bridge_call_recorded(session_id, "dynamic_list_sort_by_column", {
|
|
8434
|
+
"name": "Список",
|
|
8435
|
+
"title": "",
|
|
8436
|
+
"column_title": "Это основная конфигурация",
|
|
8437
|
+
})
|
|
8438
|
+
ordered = bool(sort_result.get("ordered")) if isinstance(sort_result, dict) else False
|
|
8439
|
+
for direction, label in (("first", "first_after_sort"), ("last", "last_after_sort")):
|
|
8440
|
+
move_result = await _bridge_call_recorded(session_id, "table_move_row", {
|
|
8421
8441
|
"name": "Список",
|
|
8422
8442
|
"title": "",
|
|
8423
|
-
"
|
|
8443
|
+
"direction": direction,
|
|
8444
|
+
"steps": 1,
|
|
8424
8445
|
})
|
|
8425
|
-
# УстановитьПорядок() toggles the sort direction if the list is already
|
|
8426
|
-
# sorted by the same column. Read the current/top row after sorting; if
|
|
8427
|
-
# the first direction puts Нет first, toggle once and read again.
|
|
8428
8446
|
row_result = await _bridge_call_recorded(session_id, "table_current_row", {"name": "Список", "title": ""})
|
|
8429
8447
|
current_row = _table_row_pairs(row_result)
|
|
8430
8448
|
main = _configuration_from_sorted_first_row(current_row)
|
|
8431
8449
|
sort_attempts.append({
|
|
8432
|
-
"attempt":
|
|
8433
|
-
"ordered":
|
|
8434
|
-
"
|
|
8435
|
-
"
|
|
8436
|
-
"
|
|
8450
|
+
"attempt": len(sort_attempts) + 1,
|
|
8451
|
+
"ordered": ordered,
|
|
8452
|
+
"move_direction": direction,
|
|
8453
|
+
"move_result": move_result if isinstance(move_result, dict) else {},
|
|
8454
|
+
"read_method": label,
|
|
8455
|
+
"row_is_main": bool(main),
|
|
8456
|
+
"row_main_marker": _row_value(current_row, "Это основная конфигурация", "ЭтоОсновнаяКонфигурация"),
|
|
8437
8457
|
})
|
|
8438
8458
|
if main:
|
|
8439
8459
|
break
|
|
8440
8460
|
|
|
8441
8461
|
if not main:
|
|
8442
|
-
warnings.append("Sorted
|
|
8462
|
+
warnings.append("Sorted edge list rows did not expose the main configuration; falling back to MXL list output")
|
|
8443
8463
|
source_method = "list_output_mxl"
|
|
8444
8464
|
output_result = await _bridge_call_recorded(session_id, "dynamic_list_output", {
|
|
8445
8465
|
"button": "",
|
|
@@ -8465,7 +8485,7 @@ async def configuration_name_version_from_subsystems(
|
|
|
8465
8485
|
"configuration_version": main.get("configuration_version", ""),
|
|
8466
8486
|
"main_configuration_row": main,
|
|
8467
8487
|
"main_configuration_rows_count": 1 if main else 0,
|
|
8468
|
-
"rows_count": 1 if source_method == "
|
|
8488
|
+
"rows_count": 1 if source_method == "sorted_edge_row" and current_row else max(0, len(cells) - 1),
|
|
8469
8489
|
"warnings": warnings,
|
|
8470
8490
|
"navigation_link": navigation_link,
|
|
8471
8491
|
"source": "РегистрСведений.ВерсииПодсистем",
|
|
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
|
{answer42-0.4.63 → answer42-0.4.64}/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
|
{answer42-0.4.63 → answer42-0.4.64}/src/mcp_1c/assets/skills/answer42-universal-report/SKILL.md
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
|