answer42 0.4.98__tar.gz → 0.4.99__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.98 → answer42-0.4.99}/PKG-INFO +4 -4
- {answer42-0.4.98 → answer42-0.4.99}/README.md +3 -3
- {answer42-0.4.98 → answer42-0.4.99}/pyproject.toml +1 -1
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/runtime.py +33 -6
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/server.py +8 -11
- {answer42-0.4.98 → answer42-0.4.99}/.gitignore +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/LICENSE +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/credentials.example.json +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/docs/agent-installation.md +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/docs/architecture.md +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/docs/assets/answer42-logo.png +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/docs/assets/platform42-logo.svg +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/docs/installation.md +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/scripts/build_cf.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/scripts/build_pages.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/scripts/e2e_http_smoke.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/scripts/e2e_stable.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/scripts/openclaw_mcp_autoreload.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/scripts/rag_cli.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/Configuration.xml +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl" +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/src/client_cf/ConfigDumpInfo.xml +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/client_cf/Configuration.xml +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/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.98 → answer42-0.4.99}/src/mcp_1c/__init__.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/assets/__init__.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/assets/skills/answer42-universal-report/SKILL.md +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/auth.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/bridge.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/credentials.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/os_support.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/platform.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/protocol.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/__init__.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/detect.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/dump.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/model.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/parsers.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/service.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/store.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/summary_backend.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/rag/summary_vector.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/recorder.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/release_helper.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/src/mcp_1c/skill_installer.py +0 -0
- {answer42-0.4.98 → answer42-0.4.99}/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.99
|
|
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>
|
|
@@ -164,9 +164,9 @@ answer42 install-skills --dry-run --agent all
|
|
|
164
164
|
|
|
165
165
|
## Linux display prerequisite
|
|
166
166
|
|
|
167
|
-
На Linux `start_session`
|
|
167
|
+
На Linux `start_session` использует живую X11-сессию, если процесс Answer42 унаследовал непустой `DISPLAY`: test manager и test client запускаются на этом дисплее, поэтому их окна и скриншоты видны на desktop.
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
Если `DISPLAY` не задан (headless service, SSH без X11 forwarding и т. п.), Answer42 поднимает два собственных изолированных Xvfb-дисплея: один для test manager и второй для test client. В этом режиме пакет `xvfb` обязателен:
|
|
170
170
|
|
|
171
171
|
```bash
|
|
172
172
|
# Debian / Ubuntu
|
|
@@ -176,7 +176,7 @@ sudo apt install xvfb
|
|
|
176
176
|
sudo dnf install xorg-x11-server-Xvfb
|
|
177
177
|
```
|
|
178
178
|
|
|
179
|
-
Если
|
|
179
|
+
Если не задан ни доступный `DISPLAY`, ни Xvfb, `start_session` завершается до создания ресурсов с понятной подсказкой по установке. Чтобы desktop-сервис видел живой X11, его launcher/service должен передать корректный `DISPLAY` и права доступа к X server (обычно через `XAUTHORITY`).
|
|
180
180
|
|
|
181
181
|
## Скриншоты: stdio и StreamableHTTP
|
|
182
182
|
|
|
@@ -130,9 +130,9 @@ answer42 install-skills --dry-run --agent all
|
|
|
130
130
|
|
|
131
131
|
## Linux display prerequisite
|
|
132
132
|
|
|
133
|
-
На Linux `start_session`
|
|
133
|
+
На Linux `start_session` использует живую X11-сессию, если процесс Answer42 унаследовал непустой `DISPLAY`: test manager и test client запускаются на этом дисплее, поэтому их окна и скриншоты видны на desktop.
|
|
134
134
|
|
|
135
|
-
|
|
135
|
+
Если `DISPLAY` не задан (headless service, SSH без X11 forwarding и т. п.), Answer42 поднимает два собственных изолированных Xvfb-дисплея: один для test manager и второй для test client. В этом режиме пакет `xvfb` обязателен:
|
|
136
136
|
|
|
137
137
|
```bash
|
|
138
138
|
# Debian / Ubuntu
|
|
@@ -142,7 +142,7 @@ sudo apt install xvfb
|
|
|
142
142
|
sudo dnf install xorg-x11-server-Xvfb
|
|
143
143
|
```
|
|
144
144
|
|
|
145
|
-
Если
|
|
145
|
+
Если не задан ни доступный `DISPLAY`, ни Xvfb, `start_session` завершается до создания ресурсов с понятной подсказкой по установке. Чтобы desktop-сервис видел живой X11, его launcher/service должен передать корректный `DISPLAY` и права доступа к X server (обычно через `XAUTHORITY`).
|
|
146
146
|
|
|
147
147
|
## Скриншоты: stdio и StreamableHTTP
|
|
148
148
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "answer42"
|
|
3
|
-
version = "0.4.
|
|
3
|
+
version = "0.4.99"
|
|
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"
|
|
Binary file
|
|
Binary file
|
|
@@ -118,26 +118,53 @@ def find_free_port(start: int = DEFAULT_WS_PORT, end: int | None = None) -> int:
|
|
|
118
118
|
raise RuntimeError(f"No free port found in range {start}..{end}")
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
def inherited_x11_display() -> str:
|
|
122
|
+
"""Return the caller's live X11 display, if one was intentionally inherited."""
|
|
123
|
+
if os_support.IS_WINDOWS:
|
|
124
|
+
return ""
|
|
125
|
+
return os.getenv("DISPLAY", "").strip()
|
|
126
|
+
|
|
127
|
+
|
|
121
128
|
def require_xvfb() -> str:
|
|
122
|
-
"""Return the Xvfb executable or raise an actionable
|
|
129
|
+
"""Return the Xvfb executable or raise an actionable headless prerequisite error.
|
|
123
130
|
|
|
124
|
-
|
|
125
|
-
X displays. It must therefore have Xvfb even when the MCP process already
|
|
126
|
-
has access to a live desktop ``DISPLAY``.
|
|
131
|
+
Xvfb is needed only when Answer42 did not inherit a live X11 ``DISPLAY``.
|
|
127
132
|
"""
|
|
128
133
|
if os_support.IS_WINDOWS:
|
|
129
134
|
raise RuntimeError("Xvfb is not available on Windows")
|
|
130
135
|
xvfb_bin = shutil.which("Xvfb") or "/usr/bin/Xvfb"
|
|
131
136
|
if not Path(xvfb_bin).is_file():
|
|
132
137
|
raise RuntimeError(
|
|
133
|
-
"Xvfb is required to start an Answer42 session on Linux
|
|
134
|
-
"
|
|
138
|
+
"Xvfb is required to start an Answer42 session on Linux when DISPLAY is not set. "
|
|
139
|
+
"Set DISPLAY to an accessible live X11 session, or install Xvfb for headless operation. "
|
|
135
140
|
"Install the 'xvfb' package (Debian/Ubuntu: sudo apt install xvfb; Fedora/RHEL: sudo dnf install xorg-x11-server-Xvfb) "
|
|
136
141
|
"and retry start_session."
|
|
137
142
|
)
|
|
138
143
|
return xvfb_bin
|
|
139
144
|
|
|
140
145
|
|
|
146
|
+
def session_displays(display_offset: int) -> tuple[str, str, bool]:
|
|
147
|
+
"""Choose inherited desktop display or two Answer42-owned Xvfb displays.
|
|
148
|
+
|
|
149
|
+
Returns ``(manager_display, client_display, starts_xvfb)``. A live X11
|
|
150
|
+
display is deliberately shared by manager and client: it is the caller's
|
|
151
|
+
explicit request to run visibly on that desktop. Otherwise the historical
|
|
152
|
+
isolated two-Xvfb setup is retained for headless operation.
|
|
153
|
+
"""
|
|
154
|
+
desktop_display = inherited_x11_display()
|
|
155
|
+
if desktop_display:
|
|
156
|
+
return desktop_display, desktop_display, False
|
|
157
|
+
if os_support.IS_WINDOWS:
|
|
158
|
+
return "", "", False
|
|
159
|
+
require_xvfb()
|
|
160
|
+
manager_display = find_free_display(DEFAULT_DISPLAY_START + display_offset)
|
|
161
|
+
# The first X socket does not exist until start_xvfb() is called, so derive
|
|
162
|
+
# the second search position from the selected number instead of asking the
|
|
163
|
+
# same free-display scan twice.
|
|
164
|
+
client_display = find_free_display(int(manager_display.removeprefix(":")) + 1)
|
|
165
|
+
return manager_display, client_display, True
|
|
166
|
+
|
|
167
|
+
|
|
141
168
|
def start_xvfb(display: str, resolution: str = DEFAULT_DISPLAY_RES) -> subprocess.Popen:
|
|
142
169
|
"""Start Xvfb for the given display and return the Popen handle."""
|
|
143
170
|
xvfb_bin = require_xvfb()
|
|
@@ -5215,18 +5215,18 @@ async def start_session(
|
|
|
5215
5215
|
if sid in _SESSIONS:
|
|
5216
5216
|
raise ValueError(f"Session {sid!r} already exists.")
|
|
5217
5217
|
|
|
5218
|
-
# A
|
|
5219
|
-
#
|
|
5220
|
-
#
|
|
5221
|
-
|
|
5222
|
-
if not os_support.IS_WINDOWS:
|
|
5218
|
+
# A caller that inherited DISPLAY explicitly requests visible automation
|
|
5219
|
+
# on that live X11 session. In a headless process, retain two private Xvfb
|
|
5220
|
+
# displays and validate the prerequisite before allocating session state.
|
|
5221
|
+
inherited_display = runtime.inherited_x11_display()
|
|
5222
|
+
if not os_support.IS_WINDOWS and not inherited_display:
|
|
5223
5223
|
runtime.require_xvfb()
|
|
5224
5224
|
|
|
5225
5225
|
data_dir = os_support.default_data_dir() / "sessions" / sid
|
|
5226
5226
|
with _port_allocation_lock():
|
|
5227
5227
|
port_offset = _stable_session_port_offset(sid)
|
|
5228
5228
|
display_offset = port_offset // _PORT_BAND_SIZE
|
|
5229
|
-
display
|
|
5229
|
+
display, client_display, starts_xvfb = runtime.session_displays(display_offset)
|
|
5230
5230
|
ws_port = _find_session_port(runtime.DEFAULT_WS_PORT, port_offset, sub_offset=0)
|
|
5231
5231
|
ibsrv_port = _find_session_port(runtime.DEFAULT_IBSRV_HTTP_PORT, port_offset, sub_offset=0)
|
|
5232
5232
|
ibsrv_direct_regport = _find_session_port(runtime.DEFAULT_IBSRV_DIRECT_PORT, port_offset, sub_offset=0)
|
|
@@ -5256,13 +5256,10 @@ async def start_session(
|
|
|
5256
5256
|
bound_snapshot = _snapshot_for_base_url(base_url)
|
|
5257
5257
|
if bound_snapshot:
|
|
5258
5258
|
sess.rag_snapshot = bound_snapshot
|
|
5259
|
-
|
|
5259
|
+
sess.client_display = client_display
|
|
5260
|
+
if starts_xvfb:
|
|
5260
5261
|
sess.xvfb_process = runtime.start_xvfb(display)
|
|
5261
5262
|
sess.xvfb_pid = sess.xvfb_process.pid
|
|
5262
|
-
# Separate display for the test client so screenshots capture only the client window
|
|
5263
|
-
client_display = "" if os_support.IS_WINDOWS else runtime.find_free_display(runtime.DEFAULT_DISPLAY_START + display_offset + 1)
|
|
5264
|
-
sess.client_display = client_display
|
|
5265
|
-
if client_display:
|
|
5266
5263
|
sess.client_xvfb_process = runtime.start_xvfb(client_display)
|
|
5267
5264
|
sess.client_xvfb_pid = sess.client_xvfb_process.pid
|
|
5268
5265
|
await sess.bridge.start()
|
|
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.98 → answer42-0.4.99}/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
|
{answer42-0.4.98 → answer42-0.4.99}/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
|