python-hwpx-automation 6.0.3__py3-none-any.whl
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.
- hwpx_automation/__init__.py +61 -0
- hwpx_automation/__init__.pyi +27 -0
- hwpx_automation/__main__.py +8 -0
- hwpx_automation/agent_document.py +392 -0
- hwpx_automation/api.py +136 -0
- hwpx_automation/blind_eval.py +407 -0
- hwpx_automation/capabilities.py +110 -0
- hwpx_automation/compat.py +48 -0
- hwpx_automation/configuration.py +60 -0
- hwpx_automation/core/__init__.py +2 -0
- hwpx_automation/core/content.py +762 -0
- hwpx_automation/core/context.py +111 -0
- hwpx_automation/core/diff.py +53 -0
- hwpx_automation/core/document.py +37 -0
- hwpx_automation/core/formatting.py +513 -0
- hwpx_automation/core/handles.py +24 -0
- hwpx_automation/core/locations.py +205 -0
- hwpx_automation/core/locator.py +162 -0
- hwpx_automation/core/plan.py +680 -0
- hwpx_automation/core/resources.py +42 -0
- hwpx_automation/core/search.py +296 -0
- hwpx_automation/core/transactions.py +434 -0
- hwpx_automation/core/txn.py +48 -0
- hwpx_automation/document_state.py +95 -0
- hwpx_automation/errors.py +174 -0
- hwpx_automation/execution_lock.py +15 -0
- hwpx_automation/fastmcp_adapter.py +672 -0
- hwpx_automation/form_fill.py +1177 -0
- hwpx_automation/form_output_models.py +223 -0
- hwpx_automation/handlers/__init__.py +2 -0
- hwpx_automation/handlers/_shared.py +377 -0
- hwpx_automation/handlers/agent_document.py +257 -0
- hwpx_automation/handlers/authoring.py +750 -0
- hwpx_automation/handlers/content_edit.py +1078 -0
- hwpx_automation/handlers/form_fill.py +607 -0
- hwpx_automation/handlers/layout_style.py +660 -0
- hwpx_automation/handlers/quality_render.py +566 -0
- hwpx_automation/handlers/read_export.py +1295 -0
- hwpx_automation/handlers/specialized.py +624 -0
- hwpx_automation/handlers/tracked_changes.py +589 -0
- hwpx_automation/handlers/workflow.py +105 -0
- hwpx_automation/hwp_converter.py +227 -0
- hwpx_automation/hwp_support.py +94 -0
- hwpx_automation/hwpx_ops.py +1439 -0
- hwpx_automation/identity.json +263 -0
- hwpx_automation/identity.py +18 -0
- hwpx_automation/ingest_adapters.py +85 -0
- hwpx_automation/markdown_plan.py +216 -0
- hwpx_automation/mcp_cli.py +29 -0
- hwpx_automation/metadata/tools_meta.py +40 -0
- hwpx_automation/mixed_form.py +3007 -0
- hwpx_automation/mutation_models.py +401 -0
- hwpx_automation/network_policy.py +232 -0
- hwpx_automation/office/__init__.py +14 -0
- hwpx_automation/office/agent/__init__.py +125 -0
- hwpx_automation/office/agent/_batch_verification.py +383 -0
- hwpx_automation/office/agent/blueprint/__init__.py +58 -0
- hwpx_automation/office/agent/blueprint/bundle.py +282 -0
- hwpx_automation/office/agent/blueprint/catalog.py +136 -0
- hwpx_automation/office/agent/blueprint/dump.py +520 -0
- hwpx_automation/office/agent/blueprint/mapping.py +312 -0
- hwpx_automation/office/agent/blueprint/model.py +722 -0
- hwpx_automation/office/agent/blueprint/native.py +621 -0
- hwpx_automation/office/agent/blueprint/replay.py +622 -0
- hwpx_automation/office/agent/catalog.py +252 -0
- hwpx_automation/office/agent/cli.py +647 -0
- hwpx_automation/office/agent/commands.py +1383 -0
- hwpx_automation/office/agent/document.py +801 -0
- hwpx_automation/office/agent/form_plan.py +1760 -0
- hwpx_automation/office/agent/model.py +808 -0
- hwpx_automation/office/agent/path.py +155 -0
- hwpx_automation/office/agent/query.py +230 -0
- hwpx_automation/office/agent/story.py +207 -0
- hwpx_automation/office/authoring/__init__.py +3542 -0
- hwpx_automation/office/authoring/advanced_generators.py +154 -0
- hwpx_automation/office/authoring/builder/__init__.py +52 -0
- hwpx_automation/office/authoring/builder/core.py +996 -0
- hwpx_automation/office/authoring/builder/report.py +195 -0
- hwpx_automation/office/authoring/design/__init__.py +30 -0
- hwpx_automation/office/authoring/design/_support.py +144 -0
- hwpx_automation/office/authoring/design/composer.py +282 -0
- hwpx_automation/office/authoring/design/harvest.py +305 -0
- hwpx_automation/office/authoring/design/plan.py +69 -0
- hwpx_automation/office/authoring/design/profile.py +88 -0
- hwpx_automation/office/authoring/design/profiles/application_form/fragments/body.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/application_form/fragments/heading.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/application_form/fragments/info_table.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/application_form/fragments/title.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/application_form/profile.json +25 -0
- hwpx_automation/office/authoring/design/profiles/application_form/template.hwpx +0 -0
- hwpx_automation/office/authoring/design/profiles/home_notice/fragments/body.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/home_notice/fragments/heading.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/home_notice/fragments/title.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/home_notice/profile.json +24 -0
- hwpx_automation/office/authoring/design/profiles/home_notice/template.hwpx +0 -0
- hwpx_automation/office/authoring/design/profiles/official_notice/fragments/body.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/official_notice/fragments/heading.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/official_notice/fragments/info_table.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/official_notice/fragments/title.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/official_notice/profile.json +25 -0
- hwpx_automation/office/authoring/design/profiles/official_notice/template.hwpx +0 -0
- hwpx_automation/office/authoring/design/profiles/report/fragments/body.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/report/fragments/heading.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/report/fragments/info_table.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/report/fragments/title.xml +1 -0
- hwpx_automation/office/authoring/design/profiles/report/profile.json +25 -0
- hwpx_automation/office/authoring/design/profiles/report/template.hwpx +0 -0
- hwpx_automation/office/authoring/design/validator.py +107 -0
- hwpx_automation/office/authoring/presets/__init__.py +22 -0
- hwpx_automation/office/authoring/presets/proposal.py +538 -0
- hwpx_automation/office/authoring/report_parser.py +141 -0
- hwpx_automation/office/authoring/style_profile.py +437 -0
- hwpx_automation/office/authoring/template_analyzer.py +657 -0
- hwpx_automation/office/compliance/__init__.py +38 -0
- hwpx_automation/office/compliance/official_lint.py +478 -0
- hwpx_automation/office/compliance/pii.py +388 -0
- hwpx_automation/office/document_ops/__init__.py +13 -0
- hwpx_automation/office/document_ops/comparison.py +62 -0
- hwpx_automation/office/document_ops/mail_merge.py +73 -0
- hwpx_automation/office/document_ops/redline.py +35 -0
- hwpx_automation/office/evalplan/__init__.py +36 -0
- hwpx_automation/office/evalplan/runtime.py +2762 -0
- hwpx_automation/office/exam/__init__.py +44 -0
- hwpx_automation/office/exam/compose.py +282 -0
- hwpx_automation/office/exam/ir.py +44 -0
- hwpx_automation/office/exam/measure.py +163 -0
- hwpx_automation/office/exam/parser.py +150 -0
- hwpx_automation/office/exam/profile.py +123 -0
- hwpx_automation/office/form_fill/__init__.py +66 -0
- hwpx_automation/office/form_fill/classification.py +108 -0
- hwpx_automation/office/form_fill/fill_residue.py +242 -0
- hwpx_automation/office/form_fill/fit/__init__.py +36 -0
- hwpx_automation/office/form_fill/fit/apply.py +24 -0
- hwpx_automation/office/form_fill/fit/engine.py +24 -0
- hwpx_automation/office/form_fill/fit/measure.py +50 -0
- hwpx_automation/office/form_fill/fit/policy.py +28 -0
- hwpx_automation/office/form_fill/fit/report.py +28 -0
- hwpx_automation/office/form_fill/fit/seal.py +457 -0
- hwpx_automation/office/form_fill/fit/wordbox.py +1343 -0
- hwpx_automation/office/form_fill/guidance.py +704 -0
- hwpx_automation/office/form_fill/quality.py +961 -0
- hwpx_automation/office/form_fill/split_run.py +333 -0
- hwpx_automation/office/form_fill/template_formfit.py +656 -0
- hwpx_automation/office/house_style/__init__.py +196 -0
- hwpx_automation/office/house_style/composition.py +68 -0
- hwpx_automation/office/house_style/data/bank.json +625 -0
- hwpx_automation/office/house_style/data/genres.json +43 -0
- hwpx_automation/office/quality/__init__.py +14 -0
- hwpx_automation/office/quality/page_guard.py +277 -0
- hwpx_automation/office/rendering/__init__.py +145 -0
- hwpx_automation/office/rendering/_hancom_open_rate.ps1 +374 -0
- hwpx_automation/office/rendering/_refresh_hwpx_mac.applescript +162 -0
- hwpx_automation/office/rendering/_render_hwpx.ps1 +72 -0
- hwpx_automation/office/rendering/_render_hwpx_mac.applescript +249 -0
- hwpx_automation/office/rendering/block_splits.py +76 -0
- hwpx_automation/office/rendering/detectors.py +151 -0
- hwpx_automation/office/rendering/diff.py +153 -0
- hwpx_automation/office/rendering/fixture_corpus.py +215 -0
- hwpx_automation/office/rendering/oracle.py +909 -0
- hwpx_automation/office/rendering/page_qa.py +245 -0
- hwpx_automation/office/rendering/qa_contracts.py +293 -0
- hwpx_automation/office/rendering/qa_metrics.py +241 -0
- hwpx_automation/office/rendering/worker.py +290 -0
- hwpx_automation/office/utilities/__init__.py +12 -0
- hwpx_automation/office/utilities/table_compute.py +477 -0
- hwpx_automation/ops_services/__init__.py +1 -0
- hwpx_automation/ops_services/_border_fill.py +283 -0
- hwpx_automation/ops_services/composition.py +55 -0
- hwpx_automation/ops_services/content_layout.py +322 -0
- hwpx_automation/ops_services/context.py +213 -0
- hwpx_automation/ops_services/form_fields.py +557 -0
- hwpx_automation/ops_services/media.py +178 -0
- hwpx_automation/ops_services/memo_style.py +477 -0
- hwpx_automation/ops_services/package_validation.py +166 -0
- hwpx_automation/ops_services/planning.py +201 -0
- hwpx_automation/ops_services/preview_export.py +585 -0
- hwpx_automation/ops_services/read_query.py +601 -0
- hwpx_automation/ops_services/save_policy.py +604 -0
- hwpx_automation/ops_services/tables.py +539 -0
- hwpx_automation/ops_services/transactions.py +616 -0
- hwpx_automation/preview_output_models.py +69 -0
- hwpx_automation/public-modules.json +206 -0
- hwpx_automation/py.typed +1 -0
- hwpx_automation/quality.py +351 -0
- hwpx_automation/quality_generation.py +725 -0
- hwpx_automation/runtime.py +321 -0
- hwpx_automation/runtime_services.py +100 -0
- hwpx_automation/server.py +259 -0
- hwpx_automation/storage.py +747 -0
- hwpx_automation/tool_bindings.py +170 -0
- hwpx_automation/tool_contract.py +982 -0
- hwpx_automation/upstream.py +755 -0
- hwpx_automation/utils/__init__.py +2 -0
- hwpx_automation/utils/helpers.py +29 -0
- hwpx_automation/visual_qa.py +667 -0
- hwpx_automation/workflow/__init__.py +55 -0
- hwpx_automation/workflow/adapters.py +482 -0
- hwpx_automation/workflow/dispatcher.py +213 -0
- hwpx_automation/workflow/models.py +243 -0
- hwpx_automation/workflow/policy.py +198 -0
- hwpx_automation/workflow/render_contracts.py +173 -0
- hwpx_automation/workflow/render_metrics.py +196 -0
- hwpx_automation/workflow/render_queue.py +482 -0
- hwpx_automation/workflow/render_security.py +172 -0
- hwpx_automation/workflow/render_transport.py +369 -0
- hwpx_automation/workflow/rendering.py +206 -0
- hwpx_automation/workflow/service.py +758 -0
- hwpx_automation/workflow/state_machine.py +65 -0
- hwpx_automation/workflow/store.py +747 -0
- hwpx_automation/workspace.py +1694 -0
- python_hwpx_automation-6.0.3.dist-info/METADATA +279 -0
- python_hwpx_automation-6.0.3.dist-info/RECORD +217 -0
- python_hwpx_automation-6.0.3.dist-info/WHEEL +5 -0
- python_hwpx_automation-6.0.3.dist-info/entry_points.txt +3 -0
- python_hwpx_automation-6.0.3.dist-info/licenses/LICENSE +178 -0
- python_hwpx_automation-6.0.3.dist-info/licenses/NOTICE +14 -0
- python_hwpx_automation-6.0.3.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "python-hwpx-automation.public-modules/v1",
|
|
3
|
+
"scope": "All Python modules shipped by the canonical 6.x distribution. Base-public modules must import without the optional MCP SDK; the five adapter modules require the mcp extra by design.",
|
|
4
|
+
"moduleCount": 177,
|
|
5
|
+
"moduleSha256": "4fb2c3852fef3aa83ff1c8ddbbb40feca55889b478cfabfa7e304f25c22d5c06",
|
|
6
|
+
"basePublicModuleCount": 172,
|
|
7
|
+
"basePublicModuleSha256": "ae0e52305fae27f664d71c475a9d40041c02b635955259cf9b9a622b81371547",
|
|
8
|
+
"basePublicModules": [
|
|
9
|
+
"hwpx_automation",
|
|
10
|
+
"hwpx_automation.__main__",
|
|
11
|
+
"hwpx_automation.agent_document",
|
|
12
|
+
"hwpx_automation.api",
|
|
13
|
+
"hwpx_automation.blind_eval",
|
|
14
|
+
"hwpx_automation.capabilities",
|
|
15
|
+
"hwpx_automation.compat",
|
|
16
|
+
"hwpx_automation.configuration",
|
|
17
|
+
"hwpx_automation.core",
|
|
18
|
+
"hwpx_automation.core.content",
|
|
19
|
+
"hwpx_automation.core.context",
|
|
20
|
+
"hwpx_automation.core.diff",
|
|
21
|
+
"hwpx_automation.core.document",
|
|
22
|
+
"hwpx_automation.core.formatting",
|
|
23
|
+
"hwpx_automation.core.handles",
|
|
24
|
+
"hwpx_automation.core.locations",
|
|
25
|
+
"hwpx_automation.core.locator",
|
|
26
|
+
"hwpx_automation.core.plan",
|
|
27
|
+
"hwpx_automation.core.resources",
|
|
28
|
+
"hwpx_automation.core.search",
|
|
29
|
+
"hwpx_automation.core.transactions",
|
|
30
|
+
"hwpx_automation.core.txn",
|
|
31
|
+
"hwpx_automation.document_state",
|
|
32
|
+
"hwpx_automation.errors",
|
|
33
|
+
"hwpx_automation.execution_lock",
|
|
34
|
+
"hwpx_automation.form_fill",
|
|
35
|
+
"hwpx_automation.form_output_models",
|
|
36
|
+
"hwpx_automation.handlers",
|
|
37
|
+
"hwpx_automation.handlers._shared",
|
|
38
|
+
"hwpx_automation.handlers.agent_document",
|
|
39
|
+
"hwpx_automation.handlers.authoring",
|
|
40
|
+
"hwpx_automation.handlers.content_edit",
|
|
41
|
+
"hwpx_automation.handlers.form_fill",
|
|
42
|
+
"hwpx_automation.handlers.layout_style",
|
|
43
|
+
"hwpx_automation.handlers.read_export",
|
|
44
|
+
"hwpx_automation.handlers.specialized",
|
|
45
|
+
"hwpx_automation.handlers.tracked_changes",
|
|
46
|
+
"hwpx_automation.handlers.workflow",
|
|
47
|
+
"hwpx_automation.hwp_converter",
|
|
48
|
+
"hwpx_automation.hwp_support",
|
|
49
|
+
"hwpx_automation.hwpx_ops",
|
|
50
|
+
"hwpx_automation.identity",
|
|
51
|
+
"hwpx_automation.ingest_adapters",
|
|
52
|
+
"hwpx_automation.markdown_plan",
|
|
53
|
+
"hwpx_automation.mcp_cli",
|
|
54
|
+
"hwpx_automation.metadata.tools_meta",
|
|
55
|
+
"hwpx_automation.mixed_form",
|
|
56
|
+
"hwpx_automation.mutation_models",
|
|
57
|
+
"hwpx_automation.network_policy",
|
|
58
|
+
"hwpx_automation.office",
|
|
59
|
+
"hwpx_automation.office.agent",
|
|
60
|
+
"hwpx_automation.office.agent._batch_verification",
|
|
61
|
+
"hwpx_automation.office.agent.blueprint",
|
|
62
|
+
"hwpx_automation.office.agent.blueprint.bundle",
|
|
63
|
+
"hwpx_automation.office.agent.blueprint.catalog",
|
|
64
|
+
"hwpx_automation.office.agent.blueprint.dump",
|
|
65
|
+
"hwpx_automation.office.agent.blueprint.mapping",
|
|
66
|
+
"hwpx_automation.office.agent.blueprint.model",
|
|
67
|
+
"hwpx_automation.office.agent.blueprint.native",
|
|
68
|
+
"hwpx_automation.office.agent.blueprint.replay",
|
|
69
|
+
"hwpx_automation.office.agent.catalog",
|
|
70
|
+
"hwpx_automation.office.agent.cli",
|
|
71
|
+
"hwpx_automation.office.agent.commands",
|
|
72
|
+
"hwpx_automation.office.agent.document",
|
|
73
|
+
"hwpx_automation.office.agent.form_plan",
|
|
74
|
+
"hwpx_automation.office.agent.model",
|
|
75
|
+
"hwpx_automation.office.agent.path",
|
|
76
|
+
"hwpx_automation.office.agent.query",
|
|
77
|
+
"hwpx_automation.office.agent.story",
|
|
78
|
+
"hwpx_automation.office.authoring",
|
|
79
|
+
"hwpx_automation.office.authoring.advanced_generators",
|
|
80
|
+
"hwpx_automation.office.authoring.builder",
|
|
81
|
+
"hwpx_automation.office.authoring.builder.core",
|
|
82
|
+
"hwpx_automation.office.authoring.builder.report",
|
|
83
|
+
"hwpx_automation.office.authoring.design",
|
|
84
|
+
"hwpx_automation.office.authoring.design._support",
|
|
85
|
+
"hwpx_automation.office.authoring.design.composer",
|
|
86
|
+
"hwpx_automation.office.authoring.design.harvest",
|
|
87
|
+
"hwpx_automation.office.authoring.design.plan",
|
|
88
|
+
"hwpx_automation.office.authoring.design.profile",
|
|
89
|
+
"hwpx_automation.office.authoring.design.validator",
|
|
90
|
+
"hwpx_automation.office.authoring.presets",
|
|
91
|
+
"hwpx_automation.office.authoring.presets.proposal",
|
|
92
|
+
"hwpx_automation.office.authoring.report_parser",
|
|
93
|
+
"hwpx_automation.office.authoring.style_profile",
|
|
94
|
+
"hwpx_automation.office.authoring.template_analyzer",
|
|
95
|
+
"hwpx_automation.office.compliance",
|
|
96
|
+
"hwpx_automation.office.compliance.official_lint",
|
|
97
|
+
"hwpx_automation.office.compliance.pii",
|
|
98
|
+
"hwpx_automation.office.document_ops",
|
|
99
|
+
"hwpx_automation.office.document_ops.comparison",
|
|
100
|
+
"hwpx_automation.office.document_ops.mail_merge",
|
|
101
|
+
"hwpx_automation.office.document_ops.redline",
|
|
102
|
+
"hwpx_automation.office.evalplan",
|
|
103
|
+
"hwpx_automation.office.evalplan.runtime",
|
|
104
|
+
"hwpx_automation.office.exam",
|
|
105
|
+
"hwpx_automation.office.exam.compose",
|
|
106
|
+
"hwpx_automation.office.exam.ir",
|
|
107
|
+
"hwpx_automation.office.exam.measure",
|
|
108
|
+
"hwpx_automation.office.exam.parser",
|
|
109
|
+
"hwpx_automation.office.exam.profile",
|
|
110
|
+
"hwpx_automation.office.form_fill",
|
|
111
|
+
"hwpx_automation.office.form_fill.classification",
|
|
112
|
+
"hwpx_automation.office.form_fill.fill_residue",
|
|
113
|
+
"hwpx_automation.office.form_fill.fit",
|
|
114
|
+
"hwpx_automation.office.form_fill.fit.apply",
|
|
115
|
+
"hwpx_automation.office.form_fill.fit.engine",
|
|
116
|
+
"hwpx_automation.office.form_fill.fit.measure",
|
|
117
|
+
"hwpx_automation.office.form_fill.fit.policy",
|
|
118
|
+
"hwpx_automation.office.form_fill.fit.report",
|
|
119
|
+
"hwpx_automation.office.form_fill.fit.seal",
|
|
120
|
+
"hwpx_automation.office.form_fill.fit.wordbox",
|
|
121
|
+
"hwpx_automation.office.form_fill.guidance",
|
|
122
|
+
"hwpx_automation.office.form_fill.quality",
|
|
123
|
+
"hwpx_automation.office.form_fill.split_run",
|
|
124
|
+
"hwpx_automation.office.form_fill.template_formfit",
|
|
125
|
+
"hwpx_automation.office.house_style",
|
|
126
|
+
"hwpx_automation.office.house_style.composition",
|
|
127
|
+
"hwpx_automation.office.quality",
|
|
128
|
+
"hwpx_automation.office.quality.page_guard",
|
|
129
|
+
"hwpx_automation.office.rendering",
|
|
130
|
+
"hwpx_automation.office.rendering.block_splits",
|
|
131
|
+
"hwpx_automation.office.rendering.detectors",
|
|
132
|
+
"hwpx_automation.office.rendering.diff",
|
|
133
|
+
"hwpx_automation.office.rendering.fixture_corpus",
|
|
134
|
+
"hwpx_automation.office.rendering.oracle",
|
|
135
|
+
"hwpx_automation.office.rendering.page_qa",
|
|
136
|
+
"hwpx_automation.office.rendering.qa_contracts",
|
|
137
|
+
"hwpx_automation.office.rendering.qa_metrics",
|
|
138
|
+
"hwpx_automation.office.rendering.worker",
|
|
139
|
+
"hwpx_automation.office.utilities",
|
|
140
|
+
"hwpx_automation.office.utilities.table_compute",
|
|
141
|
+
"hwpx_automation.ops_services",
|
|
142
|
+
"hwpx_automation.ops_services._border_fill",
|
|
143
|
+
"hwpx_automation.ops_services.composition",
|
|
144
|
+
"hwpx_automation.ops_services.content_layout",
|
|
145
|
+
"hwpx_automation.ops_services.context",
|
|
146
|
+
"hwpx_automation.ops_services.form_fields",
|
|
147
|
+
"hwpx_automation.ops_services.media",
|
|
148
|
+
"hwpx_automation.ops_services.memo_style",
|
|
149
|
+
"hwpx_automation.ops_services.package_validation",
|
|
150
|
+
"hwpx_automation.ops_services.planning",
|
|
151
|
+
"hwpx_automation.ops_services.preview_export",
|
|
152
|
+
"hwpx_automation.ops_services.read_query",
|
|
153
|
+
"hwpx_automation.ops_services.save_policy",
|
|
154
|
+
"hwpx_automation.ops_services.tables",
|
|
155
|
+
"hwpx_automation.ops_services.transactions",
|
|
156
|
+
"hwpx_automation.preview_output_models",
|
|
157
|
+
"hwpx_automation.quality",
|
|
158
|
+
"hwpx_automation.quality_generation",
|
|
159
|
+
"hwpx_automation.runtime_services",
|
|
160
|
+
"hwpx_automation.storage",
|
|
161
|
+
"hwpx_automation.tool_contract",
|
|
162
|
+
"hwpx_automation.upstream",
|
|
163
|
+
"hwpx_automation.utils",
|
|
164
|
+
"hwpx_automation.utils.helpers",
|
|
165
|
+
"hwpx_automation.visual_qa",
|
|
166
|
+
"hwpx_automation.workflow",
|
|
167
|
+
"hwpx_automation.workflow.adapters",
|
|
168
|
+
"hwpx_automation.workflow.dispatcher",
|
|
169
|
+
"hwpx_automation.workflow.models",
|
|
170
|
+
"hwpx_automation.workflow.policy",
|
|
171
|
+
"hwpx_automation.workflow.render_contracts",
|
|
172
|
+
"hwpx_automation.workflow.render_metrics",
|
|
173
|
+
"hwpx_automation.workflow.render_queue",
|
|
174
|
+
"hwpx_automation.workflow.render_security",
|
|
175
|
+
"hwpx_automation.workflow.render_transport",
|
|
176
|
+
"hwpx_automation.workflow.rendering",
|
|
177
|
+
"hwpx_automation.workflow.service",
|
|
178
|
+
"hwpx_automation.workflow.state_machine",
|
|
179
|
+
"hwpx_automation.workflow.store",
|
|
180
|
+
"hwpx_automation.workspace"
|
|
181
|
+
],
|
|
182
|
+
"mcpAdapterModuleCount": 5,
|
|
183
|
+
"mcpAdapterModuleSha256": "89fa1f67eebb1b370021c6285be567f1926155188f5e2df35a6a4a49b1cffb61",
|
|
184
|
+
"mcpAdapterModules": [
|
|
185
|
+
{
|
|
186
|
+
"module": "hwpx_automation.fastmcp_adapter",
|
|
187
|
+
"reason": "Imports FastMCP protocol types and implements the adapter boundary."
|
|
188
|
+
},
|
|
189
|
+
{
|
|
190
|
+
"module": "hwpx_automation.handlers.quality_render",
|
|
191
|
+
"reason": "Returns MCP protocol content blocks from adapter-facing quality handlers."
|
|
192
|
+
},
|
|
193
|
+
{
|
|
194
|
+
"module": "hwpx_automation.runtime",
|
|
195
|
+
"reason": "Composes the FastMCP runtime and protocol types."
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"module": "hwpx_automation.server",
|
|
199
|
+
"reason": "Starts the optional MCP transport."
|
|
200
|
+
},
|
|
201
|
+
{
|
|
202
|
+
"module": "hwpx_automation.tool_bindings",
|
|
203
|
+
"reason": "Binds pure ToolSpec data to FastMCP runtime handlers."
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
}
|
hwpx_automation/py.typed
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1,351 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
"""Automation quality contract (VisualComplete Phase F).
|
|
3
|
+
|
|
4
|
+
Every write funnels through the one ``python-hwpx`` SavePipeline gate and reports a
|
|
5
|
+
uniform ``VisualCompleteReport``. This module owns:
|
|
6
|
+
|
|
7
|
+
* :func:`resolve_policy` — turn a model-facing ``quality`` block into a
|
|
8
|
+
:class:`~hwpx.quality.QualityPolicy` (default = transparent, i.e. today's
|
|
9
|
+
open-safety-only behaviour, so the contract is invisible until a caller opts in).
|
|
10
|
+
* :func:`save_through_pipeline` / :func:`visual_complete_block` — run the gate and
|
|
11
|
+
map the report to an MCP payload (``ok`` / ``visualComplete`` / structured
|
|
12
|
+
``errors`` carrying retry-able codes + ``suggestedRetry``).
|
|
13
|
+
* :class:`QualityGateError` — raised when an elevated policy's gate fails so the
|
|
14
|
+
write is **withheld** (fail-closed) and the model sees the structured error.
|
|
15
|
+
* the **capability handshake** (:func:`capability_state` / :func:`assert_write_capability`)
|
|
16
|
+
— core/automation/plugin versions + a hash that **fails closed on skew** (e.g. a
|
|
17
|
+
``python-hwpx`` too old to expose the SavePipeline gate).
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import hashlib
|
|
22
|
+
import importlib.util
|
|
23
|
+
import os
|
|
24
|
+
from importlib.metadata import PackageNotFoundError, version as _pkg_version
|
|
25
|
+
from pathlib import Path
|
|
26
|
+
from typing import Any, Mapping
|
|
27
|
+
|
|
28
|
+
from .configuration import canonical_env_name, env_value
|
|
29
|
+
try:
|
|
30
|
+
import tomllib
|
|
31
|
+
except ModuleNotFoundError: # Python 3.10 runtime compatibility
|
|
32
|
+
import tomli as tomllib
|
|
33
|
+
|
|
34
|
+
from .tool_contract import (
|
|
35
|
+
MIN_AUTOMATION_VERSION,
|
|
36
|
+
MIN_MCP_VERSION,
|
|
37
|
+
MIN_PYTHON_HWPX,
|
|
38
|
+
MIN_SKILL_VERSION,
|
|
39
|
+
contract_hash,
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
# FastMCP's call_tool catches a tool's exception and returns an isError result in
|
|
43
|
+
# a copied context, so the structured gate/skew error can't be caught at the
|
|
44
|
+
# dispatch boundary nor handed back via a ContextVar. A plain module global is
|
|
45
|
+
# shared across that boundary (and across threads): the exceptions stash
|
|
46
|
+
# themselves here on construction; the dispatch handler reads it back to rebuild
|
|
47
|
+
# the structured payload (codes + suggestedRetry). Dispatch is serial per request
|
|
48
|
+
# (clear-then-read brackets each call), so this is not a concurrency hazard.
|
|
49
|
+
_LAST_GATE_ERROR: Any = None
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def take_last_gate_error() -> Any:
|
|
53
|
+
"""Pop the most recent gate/skew error recorded since the last clear."""
|
|
54
|
+
|
|
55
|
+
global _LAST_GATE_ERROR
|
|
56
|
+
err = _LAST_GATE_ERROR
|
|
57
|
+
_LAST_GATE_ERROR = None
|
|
58
|
+
return err
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def clear_last_gate_error() -> None:
|
|
62
|
+
global _LAST_GATE_ERROR
|
|
63
|
+
_LAST_GATE_ERROR = None
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def _record_gate_error(err: Any) -> None:
|
|
67
|
+
global _LAST_GATE_ERROR
|
|
68
|
+
_LAST_GATE_ERROR = err
|
|
69
|
+
|
|
70
|
+
_QUALITY_ENV = canonical_env_name("QUALITY")
|
|
71
|
+
_REQUIRE_CAPABILITY_ENV = canonical_env_name("REQUIRE_CAPABILITY")
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
# --------------------------------------------------------------------------- #
|
|
75
|
+
# python-hwpx quality stack (imported lazily so this module loads even on a skew).
|
|
76
|
+
# --------------------------------------------------------------------------- #
|
|
77
|
+
def _quality_available() -> bool:
|
|
78
|
+
return importlib.util.find_spec("hwpx.quality") is not None
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def package_version(package: str) -> str:
|
|
82
|
+
module_name = {"python-hwpx": "hwpx", "python-hwpx-automation": "hwpx_automation",
|
|
83
|
+
"hwpx-mcp-server": "hwpx_automation"}.get(package)
|
|
84
|
+
if module_name:
|
|
85
|
+
spec = importlib.util.find_spec(module_name)
|
|
86
|
+
origin = Path(spec.origin).resolve() if spec and spec.origin else None
|
|
87
|
+
if origin is not None:
|
|
88
|
+
for parent in origin.parents:
|
|
89
|
+
pyproject = parent / "pyproject.toml"
|
|
90
|
+
if not pyproject.is_file():
|
|
91
|
+
continue
|
|
92
|
+
try:
|
|
93
|
+
data = tomllib.loads(pyproject.read_text(encoding="utf-8"))
|
|
94
|
+
project = data.get("project", {})
|
|
95
|
+
if project.get("name") == package and isinstance(project.get("version"), str):
|
|
96
|
+
return project["version"]
|
|
97
|
+
except (OSError, tomllib.TOMLDecodeError):
|
|
98
|
+
break
|
|
99
|
+
try:
|
|
100
|
+
return _pkg_version(package)
|
|
101
|
+
except PackageNotFoundError:
|
|
102
|
+
return "unknown"
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _version_lt(value: str, minimum: str) -> bool:
|
|
106
|
+
"""True if *value* is an older version than *minimum* (PEP 440 aware).
|
|
107
|
+
|
|
108
|
+
Uses ``packaging.version`` so that ``"2.12"`` == ``"2.12.0"`` and a
|
|
109
|
+
pre-release (``"2.12.0rc1"`` / ``".dev1"``) sorts BEFORE the final release —
|
|
110
|
+
otherwise a healthy install (or an rc of the boundary) would falsely skew and
|
|
111
|
+
fail closed.
|
|
112
|
+
"""
|
|
113
|
+
|
|
114
|
+
try:
|
|
115
|
+
from packaging.version import InvalidVersion, Version
|
|
116
|
+
|
|
117
|
+
try:
|
|
118
|
+
return Version(value) < Version(minimum)
|
|
119
|
+
except InvalidVersion:
|
|
120
|
+
pass
|
|
121
|
+
except Exception: # pragma: no cover - packaging always present via pip
|
|
122
|
+
pass
|
|
123
|
+
# Stdlib fallback: zero-pad to equal length so "2.12" is not < "2.12.0".
|
|
124
|
+
a = [int("".join(c for c in p if c.isdigit()) or 0) for p in value.split(".")]
|
|
125
|
+
b = [int("".join(c for c in p if c.isdigit()) or 0) for p in minimum.split(".")]
|
|
126
|
+
width = max(len(a), len(b))
|
|
127
|
+
a += [0] * (width - len(a))
|
|
128
|
+
b += [0] * (width - len(b))
|
|
129
|
+
return a < b
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
# --------------------------------------------------------------------------- #
|
|
133
|
+
# Quality policy resolution.
|
|
134
|
+
# --------------------------------------------------------------------------- #
|
|
135
|
+
_POLICY_KEY_MAP = {
|
|
136
|
+
"requireOpenSafety": "require_open_safety",
|
|
137
|
+
"requireVisualComplete": "require_visual_complete",
|
|
138
|
+
"requireReferenceIntegrity": "require_reference_integrity",
|
|
139
|
+
"renderCheck": "render_check",
|
|
140
|
+
"xsdMode": "xsd_mode",
|
|
141
|
+
"overflowPolicy": "overflow_policy",
|
|
142
|
+
"layoutLint": "layout_lint",
|
|
143
|
+
"allowExpertUnsafe": "allow_expert_unsafe",
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def resolve_policy(quality: Mapping[str, Any] | str | None) -> Any:
|
|
148
|
+
"""Map a model-facing ``quality`` block to a ``QualityPolicy``.
|
|
149
|
+
|
|
150
|
+
``None`` → the ``HWPX_AUTOMATION_QUALITY`` env default (with the supported
|
|
151
|
+
6.x ``HWPX_MCP_QUALITY`` fallback) → transparent. A string picks a
|
|
152
|
+
named policy (``transparent`` / ``strict``). A dict elevates from transparent
|
|
153
|
+
with camelCase overrides (``renderCheck`` / ``overflowPolicy`` / ``layoutLint`` …).
|
|
154
|
+
"""
|
|
155
|
+
|
|
156
|
+
from hwpx.quality import QualityPolicy
|
|
157
|
+
|
|
158
|
+
if quality is None:
|
|
159
|
+
quality = env_value("QUALITY", "transparent") or "transparent"
|
|
160
|
+
|
|
161
|
+
if isinstance(quality, str):
|
|
162
|
+
mode = quality.strip().lower()
|
|
163
|
+
if mode in ("strict", "docx", "full"):
|
|
164
|
+
return QualityPolicy.strict()
|
|
165
|
+
return QualityPolicy.transparent()
|
|
166
|
+
|
|
167
|
+
if isinstance(quality, Mapping):
|
|
168
|
+
mode = str(quality.get("mode", "transparent")).lower()
|
|
169
|
+
base = QualityPolicy.strict() if mode in ("strict", "docx", "full") else QualityPolicy.transparent()
|
|
170
|
+
changes: dict[str, Any] = {}
|
|
171
|
+
for key, attr in _POLICY_KEY_MAP.items():
|
|
172
|
+
if key in quality:
|
|
173
|
+
changes[attr] = quality[key]
|
|
174
|
+
return base.with_(**changes) if changes else base
|
|
175
|
+
|
|
176
|
+
return QualityPolicy.transparent()
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
# --------------------------------------------------------------------------- #
|
|
180
|
+
# Report → MCP payload.
|
|
181
|
+
# --------------------------------------------------------------------------- #
|
|
182
|
+
def visual_complete_block(report: Any) -> dict[str, Any]:
|
|
183
|
+
"""The model-facing VisualComplete block (codes + suggestedRetry)."""
|
|
184
|
+
|
|
185
|
+
errors = [
|
|
186
|
+
{
|
|
187
|
+
"code": err.code,
|
|
188
|
+
"message": err.message,
|
|
189
|
+
"suggestedRetry": err.suggested_retry,
|
|
190
|
+
}
|
|
191
|
+
for err in report.errors
|
|
192
|
+
]
|
|
193
|
+
return {
|
|
194
|
+
"ok": bool(report.ok),
|
|
195
|
+
"visualComplete": bool(report.visual_complete),
|
|
196
|
+
"status": report.visual_complete_status,
|
|
197
|
+
"renderChecked": bool(report.render_checked),
|
|
198
|
+
"errors": errors,
|
|
199
|
+
"errorCodes": [err.code for err in report.errors],
|
|
200
|
+
"warnings": list(report.warnings),
|
|
201
|
+
"suggestedRetry": _aggregate_retry(report),
|
|
202
|
+
"form": report.form.to_dict(),
|
|
203
|
+
"layout": report.layout.to_dict(),
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
def _aggregate_retry(report: Any) -> dict[str, Any] | None:
|
|
208
|
+
for err in report.errors:
|
|
209
|
+
if err.suggested_retry:
|
|
210
|
+
return {"code": err.code, **err.suggested_retry}
|
|
211
|
+
if report.errors:
|
|
212
|
+
return {"code": report.errors[0].code}
|
|
213
|
+
return None
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class QualityGateError(RuntimeError):
|
|
217
|
+
"""An elevated-policy gate failed; the write was withheld (fail-closed)."""
|
|
218
|
+
|
|
219
|
+
def __init__(self, report: Any) -> None:
|
|
220
|
+
block = visual_complete_block(report)
|
|
221
|
+
self.report = report
|
|
222
|
+
self.block = block
|
|
223
|
+
self.code = (block["errorCodes"] or ["VISUAL_COMPLETE_FAILED"])[0]
|
|
224
|
+
message = "; ".join(e["message"] for e in block["errors"]) or "visual_complete gate failed"
|
|
225
|
+
_record_gate_error(self)
|
|
226
|
+
super().__init__(message)
|
|
227
|
+
|
|
228
|
+
|
|
229
|
+
def save_through_pipeline(document: Any, output_path: Any, *, quality: Any = None) -> Any:
|
|
230
|
+
"""Save *document* through the SavePipeline; return the ``VisualCompleteReport``.
|
|
231
|
+
|
|
232
|
+
Raises :class:`QualityGateError` when the gate fails (so the caller withholds
|
|
233
|
+
the output — fail-closed). Open-safety serialize failures still raise the
|
|
234
|
+
library's ``ValueError`` as before.
|
|
235
|
+
"""
|
|
236
|
+
|
|
237
|
+
# Accept a ready QualityPolicy, or resolve None/str/dict into one.
|
|
238
|
+
if quality is None or isinstance(quality, (str, Mapping)):
|
|
239
|
+
policy = resolve_policy(quality)
|
|
240
|
+
else:
|
|
241
|
+
policy = quality
|
|
242
|
+
from .office.rendering import bind_document_rendering
|
|
243
|
+
|
|
244
|
+
with bind_document_rendering(document):
|
|
245
|
+
report = document.save_report(output_path, quality=policy)
|
|
246
|
+
if not report.ok:
|
|
247
|
+
raise QualityGateError(report)
|
|
248
|
+
return report
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
# --------------------------------------------------------------------------- #
|
|
252
|
+
# Capability handshake (fail-closed on skew).
|
|
253
|
+
# --------------------------------------------------------------------------- #
|
|
254
|
+
def capability_state() -> dict[str, Any]:
|
|
255
|
+
"""Core/automation/plugin versions + a fingerprint hash + any version skew."""
|
|
256
|
+
|
|
257
|
+
core = package_version("python-hwpx")
|
|
258
|
+
automation = package_version("python-hwpx-automation")
|
|
259
|
+
plugin = os.environ.get("HWPX_SKILL_VERSION", "unknown")
|
|
260
|
+
has_pipeline = _quality_available()
|
|
261
|
+
|
|
262
|
+
skew: list[str] = []
|
|
263
|
+
if not has_pipeline:
|
|
264
|
+
skew.append("python-hwpx is missing the hwpx.quality SavePipeline gate")
|
|
265
|
+
elif _version_lt(core, MIN_PYTHON_HWPX):
|
|
266
|
+
skew.append(f"python-hwpx {core} < required {MIN_PYTHON_HWPX}")
|
|
267
|
+
if automation == "unknown":
|
|
268
|
+
skew.append("python-hwpx-automation version is unresolved")
|
|
269
|
+
elif _version_lt(automation, MIN_AUTOMATION_VERSION):
|
|
270
|
+
skew.append(
|
|
271
|
+
f"python-hwpx-automation {automation} < required {MIN_AUTOMATION_VERSION}"
|
|
272
|
+
)
|
|
273
|
+
if plugin != "unknown" and _version_lt(plugin, MIN_SKILL_VERSION):
|
|
274
|
+
skew.append(f"hwpx skill {plugin} < required {MIN_SKILL_VERSION}")
|
|
275
|
+
|
|
276
|
+
fingerprint = hashlib.sha256(
|
|
277
|
+
"|".join(
|
|
278
|
+
[
|
|
279
|
+
"core", core,
|
|
280
|
+
"automation", automation,
|
|
281
|
+
"plugin", plugin,
|
|
282
|
+
"pipeline", str(has_pipeline),
|
|
283
|
+
"toolContract", contract_hash(),
|
|
284
|
+
]
|
|
285
|
+
).encode()
|
|
286
|
+
).hexdigest()[:16]
|
|
287
|
+
|
|
288
|
+
return {
|
|
289
|
+
"versions": {
|
|
290
|
+
"core": core,
|
|
291
|
+
"automation": automation,
|
|
292
|
+
# 6.x compatibility alias.
|
|
293
|
+
"mcp": automation,
|
|
294
|
+
"plugin": plugin,
|
|
295
|
+
},
|
|
296
|
+
"minPythonHwpx": MIN_PYTHON_HWPX,
|
|
297
|
+
"minAutomationVersion": MIN_AUTOMATION_VERSION,
|
|
298
|
+
# 6.x compatibility alias.
|
|
299
|
+
"minMcpVersion": MIN_MCP_VERSION,
|
|
300
|
+
"minSkillVersion": MIN_SKILL_VERSION,
|
|
301
|
+
"savePipelineAvailable": has_pipeline,
|
|
302
|
+
"toolContractHash": contract_hash(),
|
|
303
|
+
"hash": fingerprint,
|
|
304
|
+
"skew": skew,
|
|
305
|
+
"ok": not skew,
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
def fail_closed_enabled() -> bool:
|
|
310
|
+
return env_value("REQUIRE_CAPABILITY", "1") != "0"
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def assert_write_capability() -> None:
|
|
314
|
+
"""Raise :class:`QualityGateError`-style failure if capability is skewed.
|
|
315
|
+
|
|
316
|
+
Fail-closed: a write must not proceed when the installed quality stack can't
|
|
317
|
+
honour the gate (e.g. a stale python-hwpx). Disable with
|
|
318
|
+
``HWPX_AUTOMATION_REQUIRE_CAPABILITY=0`` for an expert/debug bypass. The
|
|
319
|
+
old ``HWPX_MCP_REQUIRE_CAPABILITY`` spelling remains a 6.x fallback.
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
if not fail_closed_enabled():
|
|
323
|
+
return
|
|
324
|
+
state = capability_state()
|
|
325
|
+
if not state["ok"]:
|
|
326
|
+
raise CapabilitySkewError(state)
|
|
327
|
+
|
|
328
|
+
|
|
329
|
+
class CapabilitySkewError(RuntimeError):
|
|
330
|
+
"""The core/automation/plugin handshake detected skew; writes fail closed."""
|
|
331
|
+
|
|
332
|
+
code = "CAPABILITY_SKEW"
|
|
333
|
+
|
|
334
|
+
def __init__(self, state: Mapping[str, Any]) -> None:
|
|
335
|
+
self.state = dict(state)
|
|
336
|
+
_record_gate_error(self)
|
|
337
|
+
super().__init__("; ".join(state.get("skew", [])) or "capability skew detected")
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
__all__ = [
|
|
341
|
+
"MIN_PYTHON_HWPX",
|
|
342
|
+
"resolve_policy",
|
|
343
|
+
"save_through_pipeline",
|
|
344
|
+
"visual_complete_block",
|
|
345
|
+
"QualityGateError",
|
|
346
|
+
"CapabilitySkewError",
|
|
347
|
+
"capability_state",
|
|
348
|
+
"assert_write_capability",
|
|
349
|
+
"fail_closed_enabled",
|
|
350
|
+
"package_version",
|
|
351
|
+
]
|