answer42 0.4.78__tar.gz → 0.4.80__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.
Files changed (64) hide show
  1. {answer42-0.4.78 → answer42-0.4.80}/PKG-INFO +1 -1
  2. {answer42-0.4.78 → answer42-0.4.80}/pyproject.toml +1 -1
  3. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/server.py +18 -101
  4. {answer42-0.4.78 → answer42-0.4.80}/.gitignore +0 -0
  5. {answer42-0.4.78 → answer42-0.4.80}/LICENSE +0 -0
  6. {answer42-0.4.78 → answer42-0.4.80}/README.md +0 -0
  7. {answer42-0.4.78 → answer42-0.4.80}/credentials.example.json +0 -0
  8. {answer42-0.4.78 → answer42-0.4.80}/docs/agent-installation.md +0 -0
  9. {answer42-0.4.78 → answer42-0.4.80}/docs/architecture.md +0 -0
  10. {answer42-0.4.78 → answer42-0.4.80}/docs/assets/answer42-logo.png +0 -0
  11. {answer42-0.4.78 → answer42-0.4.80}/docs/assets/platform42-logo.svg +0 -0
  12. {answer42-0.4.78 → answer42-0.4.80}/docs/installation.md +0 -0
  13. {answer42-0.4.78 → answer42-0.4.80}/scripts/build_cf.py +0 -0
  14. {answer42-0.4.78 → answer42-0.4.80}/scripts/build_pages.py +0 -0
  15. {answer42-0.4.78 → answer42-0.4.80}/scripts/e2e_http_smoke.py +0 -0
  16. {answer42-0.4.78 → answer42-0.4.80}/scripts/e2e_stable.py +0 -0
  17. {answer42-0.4.78 → answer42-0.4.80}/scripts/openclaw_mcp_autoreload.py +0 -0
  18. {answer42-0.4.78 → answer42-0.4.80}/scripts/rag_cli.py +0 -0
  19. {answer42-0.4.78 → answer42-0.4.80}/src/cf/ConfigDumpInfo.xml +0 -0
  20. {answer42-0.4.78 → answer42-0.4.80}/src/cf/Configuration.xml +0 -0
  21. {answer42-0.4.78 → answer42-0.4.80}/src/cf/DataProcessors/MCPTestManager/Ext/ObjectModule.bsl +0 -0
  22. {answer42-0.4.78 → answer42-0.4.80}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form/Module.bsl" +0 -0
  23. {answer42-0.4.78 → answer42-0.4.80}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260/Ext/Form.xml" +0 -0
  24. {answer42-0.4.78 → answer42-0.4.80}/src/cf/DataProcessors/MCPTestManager/Forms//320/244/320/276/321/200/320/274/320/260.xml" +0 -0
  25. {answer42-0.4.78 → answer42-0.4.80}/src/cf/DataProcessors/MCPTestManager.xml +0 -0
  26. {answer42-0.4.78 → answer42-0.4.80}/src/cf/Ext/ManagedApplicationModule.bsl +0 -0
  27. {answer42-0.4.78 → answer42-0.4.80}/src/cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
  28. {answer42-0.4.78 → answer42-0.4.80}/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
  29. {answer42-0.4.78 → answer42-0.4.80}/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
  30. {answer42-0.4.78 → answer42-0.4.80}/src/client_cf/ConfigDumpInfo.xml +0 -0
  31. {answer42-0.4.78 → answer42-0.4.80}/src/client_cf/Configuration.xml +0 -0
  32. {answer42-0.4.78 → answer42-0.4.80}/src/client_cf/Languages//320/240/321/203/321/201/321/201/320/272/320/270/320/271.xml" +0 -0
  33. {answer42-0.4.78 → answer42-0.4.80}/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
  34. {answer42-0.4.78 → answer42-0.4.80}/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
  35. {answer42-0.4.78 → answer42-0.4.80}/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
  36. {answer42-0.4.78 → answer42-0.4.80}/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
  37. {answer42-0.4.78 → answer42-0.4.80}/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
  38. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/__init__.py +0 -0
  39. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/assets/MCPTestClient.cf +0 -0
  40. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/assets/MCPTestManager.cf +0 -0
  41. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/assets/__init__.py +0 -0
  42. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/assets/skills/answer42/SKILL.md +0 -0
  43. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/assets/skills/answer42-rag/SKILL.md +0 -0
  44. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/assets/skills/answer42-universal-report/SKILL.md +0 -0
  45. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/auth.py +0 -0
  46. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/bridge.py +0 -0
  47. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/credentials.py +0 -0
  48. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/os_support.py +0 -0
  49. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/platform.py +0 -0
  50. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/protocol.py +0 -0
  51. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/__init__.py +0 -0
  52. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/detect.py +0 -0
  53. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/dump.py +0 -0
  54. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/model.py +0 -0
  55. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/parsers.py +0 -0
  56. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/service.py +0 -0
  57. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/store.py +0 -0
  58. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/summary_backend.py +0 -0
  59. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/rag/summary_vector.py +0 -0
  60. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/recorder.py +0 -0
  61. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/release_helper.py +0 -0
  62. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/runtime.py +0 -0
  63. {answer42-0.4.78 → answer42-0.4.80}/src/mcp_1c/skill_installer.py +0 -0
  64. {answer42-0.4.78 → answer42-0.4.80}/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.78
3
+ Version: 0.4.80
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.78"
3
+ version = "0.4.80"
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"
@@ -8178,53 +8178,22 @@ async def _set_universal_report_quick_setting_by_titles(
8178
8178
  return False
8179
8179
 
8180
8180
 
8181
- async def _configure_universal_report_metadata_settings(session_id: str, query: str = "") -> list[str]:
8182
- del query
8183
- warnings: list[str] = []
8184
- await _bridge_call_recorded(session_id, "click_button", {"name": "ВсеНастройки"}, timeout=30)
8185
- try:
8186
- await _bridge_call_recorded(session_id, "group_activate_page", {
8187
- "name": "СтраницыНастроек",
8188
- "page_name": "СтраницаВыбранныеПоляИСортировки",
8189
- "page_title": "Поля и сортировки",
8190
- }, timeout=15)
8191
- except Exception as exc:
8192
- warnings.append(f"Universal report selected-fields page activation failed: {exc}")
8193
- selected_fields = []
8194
- try:
8195
- rows_result = await _bridge_call_recorded(session_id, "table_rows", {"name": "ВыбранныеПоля", "limit": 80}, timeout=10)
8196
- rows = rows_result.get("rows", []) if isinstance(rows_result, dict) else []
8197
- for row in rows:
8198
- row_pairs = _table_row_pairs(row)
8199
- field = _row_value(row_pairs, "Поле")
8200
- use = _row_value(row_pairs, "Использование")
8201
- if field and field != "Поля":
8202
- selected_fields.append((field, use))
8203
- except Exception as exc:
8204
- warnings.append(f"Universal report selected fields inspection failed: {exc}")
8205
- required = {"Полное имя", "Синоним"}
8206
- selected_names = {field for field, _use in selected_fields}
8207
- enabled_names = {field for field, use in selected_fields if _is_truthy_1c(use)}
8208
- missing = sorted(required - selected_names)
8209
- disabled = sorted(required - enabled_names)
8210
- if missing:
8211
- warnings.append(
8212
- "Universal report selected fields were not detected in selected-fields table;"
8213
- f" automatic modal add skipped: {', '.join(missing)}"
8214
- )
8215
- if disabled:
8181
+ async def _form_universal_report_metadata_source(session_id: str) -> list[str]:
8182
+ warnings = [
8183
+ "Universal report settings UI was not opened; using confirmed source and parser-side metadata filtering"
8184
+ ]
8185
+ form_result = await _dangerous_bridge_call_recorded(
8186
+ session_id,
8187
+ "click_button",
8188
+ {"name": "СформироватьОтчет"},
8189
+ timeout=180,
8190
+ danger="metadata_objects_universal_report_form_may_block_thin_client",
8191
+ )
8192
+ if isinstance(form_result, dict) and form_result.get("started_long_action"):
8216
8193
  warnings.append(
8217
- "Universal report selected fields are not enabled in UI settings;"
8218
- f" leaving report settings unchanged and relying on parse/post-filtering: {', '.join(disabled)}"
8194
+ "Universal report form action is still running or blocked the interface;"
8195
+ f" form_result={_truncate_value(form_result)}"
8219
8196
  )
8220
- # Do not add report-level filters here. On live BSP Universal Report forms
8221
- # the filter-add button can open the formula editor instead of the field
8222
- # chooser, leaving the tool in an unrelated modal form. Correctness is
8223
- # enforced by the confirmed report source plus parser-side validation and
8224
- # metadata-row filtering; this keeps the user-visible report on the right
8225
- # catalog without risking another noisy/stuck UI mutation.
8226
- warnings.append("Universal report row filters were not mutated; using confirmed source and parser-side metadata filtering")
8227
- await _bridge_call_recorded(session_id, "click_button", {"name": "ЗакрытьИСформировать"}, timeout=35)
8228
8197
  return warnings
8229
8198
 
8230
8199
 
@@ -8246,24 +8215,7 @@ def _universal_report_metadata_source_title_found(value: Any) -> bool:
8246
8215
  return False
8247
8216
 
8248
8217
 
8249
- def _active_window_looks_like_startup_noise(value: Any) -> bool:
8250
- if not isinstance(value, dict):
8251
- return False
8252
- title = str(value.get("title") or "")
8253
- form_name = str(value.get("form_name") or "")
8254
- diagnostics = value.get("client_diagnostics") if isinstance(value.get("client_diagnostics"), dict) else {}
8255
- diagnostic_title = str(diagnostics.get("active_window_title") or diagnostics.get("modal_title") or "")
8256
- diagnostic_form = str(diagnostics.get("active_form_name") or diagnostics.get("modal_form_name") or "")
8257
- return (
8258
- title.startswith("Новое в версии")
8259
- or diagnostic_title.startswith("Новое в версии")
8260
- or "Справочник.Новости.Форма.ФормаНовости" in form_name
8261
- or "Справочник.Новости.Форма.ФормаНовости" in diagnostic_form
8262
- )
8263
-
8264
-
8265
8218
  async def _active_universal_report_window(session_id: str, warnings: list[str], *, timeout: int = 30) -> dict[str, Any]:
8266
- navigation_link = "e1cib/app/Отчет.УниверсальныйОтчет"
8267
8219
  deadline = time.monotonic() + max(timeout, 1)
8268
8220
  last: dict[str, Any] = {}
8269
8221
  while time.monotonic() < deadline:
@@ -8275,21 +8227,6 @@ async def _active_universal_report_window(session_id: str, warnings: list[str],
8275
8227
  form_name = str(active.get("form_name") or "")
8276
8228
  if "Универсальный отчет" in title or form_name == "ОбщаяФорма.ФормаОтчета":
8277
8229
  return active
8278
- if _active_window_looks_like_startup_noise(active):
8279
- await _bridge_call_recorded(session_id, "close_form", {}, timeout=15)
8280
- warnings.append("Startup/news form was closed before Universal report source selection")
8281
- try:
8282
- await _bridge_call_recorded(
8283
- session_id,
8284
- "open_navigation_link",
8285
- {"navigation_link": navigation_link},
8286
- timeout=20,
8287
- )
8288
- warnings.append("Universal report navigation was retried after closing startup/news form")
8289
- except Exception as exc:
8290
- warnings.append(f"Universal report navigation retry after startup/news form failed: {exc}")
8291
- await asyncio.sleep(1)
8292
- continue
8293
8230
  except Exception as exc:
8294
8231
  warnings.append(f"Universal report active-window wait probe failed: {exc}")
8295
8232
  await asyncio.sleep(1)
@@ -8396,30 +8333,10 @@ async def _metadata_rows_from_universal_report(
8396
8333
  " refusing to read arbitrary current Universal report result"
8397
8334
  ),
8398
8335
  ]
8399
- try:
8400
- settings_warnings = await _configure_universal_report_metadata_settings(session_id, query)
8401
- warnings.extend(settings_warnings)
8402
- settings_applied = True
8403
- except Exception as exc:
8404
- settings_applied = False
8405
- warnings.append(
8406
- "Universal report settings UI failed; falling back to report formation only"
8407
- f"; error={exc}"
8408
- )
8409
- if not settings_applied:
8410
- form_result = await _dangerous_bridge_call_recorded(
8411
- session_id,
8412
- "click_button",
8413
- {"name": "СформироватьОтчет"},
8414
- timeout=180,
8415
- danger="metadata_objects_universal_report_form_may_block_thin_client",
8416
- )
8417
- if isinstance(form_result, dict) and form_result.get("started_long_action"):
8418
- warnings.append(
8419
- "Universal report form action is still running or blocked the interface;"
8420
- f" form_result={_truncate_value(form_result)}"
8421
- )
8422
- return [], warnings
8336
+ form_warnings = await _form_universal_report_metadata_source(session_id)
8337
+ warnings.extend(form_warnings)
8338
+ if any("form action is still running or blocked" in warning for warning in form_warnings):
8339
+ return [], warnings
8423
8340
  ready, readiness_warnings, readiness = await _wait_tabular_document_ready(
8424
8341
  session_id,
8425
8342
  "ОтчетТабличныйДокумент",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes