Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

## Table of Contents

- [What's new (2026-06-19) — Office I/O](#whats-new-2026-06-19--office-io)
- [What's new (2026-06-19) — Agent Toolkit](#whats-new-2026-06-19--agent-toolkit)
- [What's new (2026-06-19) — Authoring & Debugging](#whats-new-2026-06-19--authoring--debugging)
- [What's new (2026-06-19) — Test & Tooling Batch](#whats-new-2026-06-19--test--tooling-batch)
Expand Down Expand Up @@ -66,6 +67,16 @@

---

## What's new (2026-06-19) — Office I/O

Headless read/write for Excel/Word/PowerPoint, full stack (facade, `AC_*`, MCP, Script Builder). Optional extra: `pip install je_auto_control[office]`. Full reference: [`docs/source/Eng/doc/new_features/v14_features_doc.rst`](docs/source/Eng/doc/new_features/v14_features_doc.rst).

- **Excel** — `read_workbook` / `write_workbook` (`AC_read_workbook` / `AC_write_workbook`, `ac_read_workbook` / `ac_write_workbook`): read an `.xlsx` worksheet into row dicts (first row = keys) and write rows back, no GUI.
- **Word** — `read_document` / `write_document` (`AC_read_document` / `AC_write_document`): read/write `.docx` paragraphs.
- **PowerPoint** — `read_presentation` / `write_presentation` (`AC_read_presentation` / `AC_write_presentation`): read per-slide text; write slides as `{title, body:[...]}`.

The backing libraries (`openpyxl`/`python-docx`/`python-pptx`) are optional — each call raises a clear error if missing, and `import je_auto_control` pulls none of them.

## What's new (2026-06-19) — Agent Toolkit

Three pure-stdlib tools for LLM/agent-driven automation, full stack (facade, `AC_*`, MCP, Script Builder). Full reference: [`docs/source/Eng/doc/new_features/v13_features_doc.rst`](docs/source/Eng/doc/new_features/v13_features_doc.rst).
Expand Down
11 changes: 11 additions & 0 deletions README/README_zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

## 目录

- [本次更新 (2026-06-19) — Office 读写](#本次更新-2026-06-19--office-读写)
- [本次更新 (2026-06-19) — Agent 工具组](#本次更新-2026-06-19--agent-工具组)
- [本次更新 (2026-06-19) — 编写与调试](#本次更新-2026-06-19--编写与调试)
- [本次更新 (2026-06-19) — 测试与工具三件套](#本次更新-2026-06-19--测试与工具三件套)
Expand Down Expand Up @@ -65,6 +66,16 @@

---

## 本次更新 (2026-06-19) — Office 读写

Excel/Word/PowerPoint 的 headless 读写,走完整五层(facade、`AC_*`、MCP、Script Builder)。可选 extra:`pip install je_auto_control[office]`。完整参考:[`docs/source/Zh/doc/new_features/v14_features_doc.rst`](../docs/source/Zh/doc/new_features/v14_features_doc.rst)。

- **Excel** — `read_workbook` / `write_workbook`(`AC_read_workbook` / `AC_write_workbook`、`ac_read_workbook` / `ac_write_workbook`):把 `.xlsx` 工作表读成数据行字典(第一行为键)并写回,不需 GUI。
- **Word** — `read_document` / `write_document`(`AC_read_document` / `AC_write_document`):读写 `.docx` 段落。
- **PowerPoint** — `read_presentation` / `write_presentation`(`AC_read_presentation` / `AC_write_presentation`):读取每张幻灯片文本;以 `{title, body:[...]}` 写入幻灯片。

背后函式库(`openpyxl`/`python-docx`/`python-pptx`)为可选——缺少时每个调用会抛出清楚错误,且 `import je_auto_control` 不会载入它们。

## 本次更新 (2026-06-19) — Agent 工具组

三项供 LLM / agent 驱动自动化使用的纯标准库工具,走完整五层(facade、`AC_*`、MCP、Script Builder)。完整参考:[`docs/source/Zh/doc/new_features/v13_features_doc.rst`](../docs/source/Zh/doc/new_features/v13_features_doc.rst)。
Expand Down
11 changes: 11 additions & 0 deletions README/README_zh-TW.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

## 目錄

- [本次更新 (2026-06-19) — Office 讀寫](#本次更新-2026-06-19--office-讀寫)
- [本次更新 (2026-06-19) — Agent 工具組](#本次更新-2026-06-19--agent-工具組)
- [本次更新 (2026-06-19) — 編寫與除錯](#本次更新-2026-06-19--編寫與除錯)
- [本次更新 (2026-06-19) — 測試與工具三件套](#本次更新-2026-06-19--測試與工具三件套)
Expand Down Expand Up @@ -65,6 +66,16 @@

---

## 本次更新 (2026-06-19) — Office 讀寫

Excel/Word/PowerPoint 的 headless 讀寫,走完整五層(facade、`AC_*`、MCP、Script Builder)。可選 extra:`pip install je_auto_control[office]`。完整參考:[`docs/source/Zh/doc/new_features/v14_features_doc.rst`](../docs/source/Zh/doc/new_features/v14_features_doc.rst)。

- **Excel** — `read_workbook` / `write_workbook`(`AC_read_workbook` / `AC_write_workbook`、`ac_read_workbook` / `ac_write_workbook`):把 `.xlsx` 工作表讀成資料列字典(第一列為鍵)並寫回,不需 GUI。
- **Word** — `read_document` / `write_document`(`AC_read_document` / `AC_write_document`):讀寫 `.docx` 段落。
- **PowerPoint** — `read_presentation` / `write_presentation`(`AC_read_presentation` / `AC_write_presentation`):讀取每張投影片文字;以 `{title, body:[...]}` 寫入投影片。

背後函式庫(`openpyxl`/`python-docx`/`python-pptx`)為可選——缺少時每個呼叫會丟出清楚錯誤,且 `import je_auto_control` 不會載入它們。

## 本次更新 (2026-06-19) — Agent 工具組

三項供 LLM / agent 驅動自動化使用的純標準庫工具,走完整五層(facade、`AC_*`、MCP、Script Builder)。完整參考:[`docs/source/Zh/doc/new_features/v13_features_doc.rst`](../docs/source/Zh/doc/new_features/v13_features_doc.rst)。
Expand Down
5 changes: 5 additions & 0 deletions dev_requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ qt-material==2.17
mss==10.2.0
defusedxml==0.7.1

# Office I/O ([office] extra) — exercised by the headless Office tests.
openpyxl==3.1.5
python-docx==1.2.0
python-pptx==1.0.2

# Quality tooling — used by .github/workflows/quality.yml and locally.
ruff==0.15.14
bandit==1.9.4
Expand Down
65 changes: 65 additions & 0 deletions docs/source/Eng/doc/new_features/v14_features_doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
============================================
New Features (2026-06-19) — Office I/O
============================================

Headless read/write for Office documents — Excel (``.xlsx``), Word
(``.docx``), and PowerPoint (``.pptx``) — so flows can ingest a row-set or
emit a report without driving the GUI. Wired through the full stack
(facade, ``AC_*`` executor commands, MCP tools, Script Builder).

The backing libraries (``openpyxl`` / ``python-docx`` / ``python-pptx``)
are an **optional** dependency::

pip install je_auto_control[office]

Each function raises a clear ``RuntimeError`` if its library is missing,
so the core package stays lean and ``import je_auto_control`` pulls none of
them.

.. contents::
:local:
:depth: 2


Excel
=====

::

from je_auto_control import read_workbook, write_workbook

write_workbook("people.xlsx", [{"name": "Ada", "age": 36}], sheet="P")
rows = read_workbook("people.xlsx", sheet="P") # [{'name': 'Ada', ...}]

The first row supplies the dict keys; ``sheet`` defaults to the active
sheet. Commands: ``AC_read_workbook`` / ``AC_write_workbook`` (and
``ac_read_workbook`` / ``ac_write_workbook``).


Word
====

::

from je_auto_control import read_document, write_document

write_document("report.docx", ["Title", "First line", "Second line"])
paragraphs = read_document("report.docx")["paragraphs"]

Commands: ``AC_read_document`` / ``AC_write_document``.


PowerPoint
==========

::

from je_auto_control import read_presentation, write_presentation

write_presentation("deck.pptx", [
{"title": "Intro", "body": ["bullet one", "bullet two"]},
])
slides = read_presentation("deck.pptx")["slides"] # per-slide text runs

Each slide spec is ``{title, body:[...]}`` on a "Title and Content"
layout. Commands: ``AC_read_presentation`` / ``AC_write_presentation``.
1 change: 1 addition & 0 deletions docs/source/Eng/eng_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ Comprehensive guides for all AutoControl features.
doc/new_features/v11_features_doc
doc/new_features/v12_features_doc
doc/new_features/v13_features_doc
doc/new_features/v14_features_doc
doc/ocr_backends/ocr_backends_doc
doc/observability/observability_doc
doc/operations_layer/operations_layer_doc
Expand Down
63 changes: 63 additions & 0 deletions docs/source/Zh/doc/new_features/v14_features_doc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
====================================
新功能 (2026-06-19) — Office 讀寫
====================================

Office 文件的 headless 讀寫——Excel(``.xlsx``)、Word(``.docx``)、
PowerPoint(``.pptx``)——讓流程不必驅動 GUI 就能吃進資料列或產出報表。
走完整五層(facade、``AC_*`` 執行器指令、MCP 工具、Script Builder)。

背後的函式庫(``openpyxl`` / ``python-docx`` / ``python-pptx``)是
**可選**相依::

pip install je_auto_control[office]

缺少對應函式庫時,每個函式都會丟出清楚的 ``RuntimeError``,因此核心
套件維持精簡,``import je_auto_control`` 不會載入任何一個。

.. contents::
:local:
:depth: 2


Excel
=====

::

from je_auto_control import read_workbook, write_workbook

write_workbook("people.xlsx", [{"name": "Ada", "age": 36}], sheet="P")
rows = read_workbook("people.xlsx", sheet="P") # [{'name': 'Ada', ...}]

第一列作為 dict 的鍵;``sheet`` 預設為作用中工作表。指令:
``AC_read_workbook`` / ``AC_write_workbook``(以及 ``ac_read_workbook`` /
``ac_write_workbook``)。


Word
====

::

from je_auto_control import read_document, write_document

write_document("report.docx", ["標題", "第一行", "第二行"])
paragraphs = read_document("report.docx")["paragraphs"]

指令:``AC_read_document`` / ``AC_write_document``。


PowerPoint
==========

::

from je_auto_control import read_presentation, write_presentation

write_presentation("deck.pptx", [
{"title": "簡介", "body": ["重點一", "重點二"]},
])
slides = read_presentation("deck.pptx")["slides"] # 每張投影片的文字

每張投影片規格為 ``{title, body:[...]}``,採用「標題及內容」版面。指令:
``AC_read_presentation`` / ``AC_write_presentation``。
1 change: 1 addition & 0 deletions docs/source/Zh/zh_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ AutoControl 所有功能的完整使用指南。
doc/new_features/v11_features_doc
doc/new_features/v12_features_doc
doc/new_features/v13_features_doc
doc/new_features/v14_features_doc
doc/ocr_backends/ocr_backends_doc
doc/observability/observability_doc
doc/operations_layer/operations_layer_doc
Expand Down
8 changes: 8 additions & 0 deletions je_auto_control/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,11 @@
)
# A2A (agent-to-agent) agent card
from je_auto_control.utils.a2a import build_agent_card, write_agent_card
# Headless Office I/O (optional [office] extra: openpyxl/python-docx/pptx)
from je_auto_control.utils.office import (
read_document, read_presentation, read_workbook,
write_document, write_presentation, write_workbook,
)
# Background popup/interrupt watchdog (unattended automation)
from je_auto_control.utils.watchdog import (
PopupWatchdog, WatchdogRule, default_popup_watchdog,
Expand Down Expand Up @@ -542,6 +547,9 @@ def start_autocontrol_gui(*args, **kwargs):
"Skill", "SkillLibrary",
"assess_text", "redact_text", "scan_text",
"build_agent_card", "write_agent_card",
"read_workbook", "write_workbook",
"read_document", "write_document",
"read_presentation", "write_presentation",
# MCP server
"AuditLogger", "HttpMCPServer", "MCPContent", "MCPPrompt",
"MCPPromptArgument", "MCPResource", "MCPServer", "MCPTool",
Expand Down
36 changes: 36 additions & 0 deletions je_auto_control/gui/script_builder/command_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,42 @@ def _add_misc_specs(specs: List[CommandSpec]) -> None:
_add_tooling_specs(specs)
_add_authoring_specs(specs)
_add_agent_specs(specs)
_add_office_specs(specs)


def _add_office_specs(specs: List[CommandSpec]) -> None:
xlsx = FieldSpec("path", FieldType.FILE_PATH)
specs.append(CommandSpec(
"AC_read_workbook", "Office", "Excel: Read Workbook",
fields=(xlsx, FieldSpec("sheet", FieldType.STRING, optional=True)),
description="Read an .xlsx worksheet into rows (needs [office] extra).",
))
specs.append(CommandSpec(
"AC_write_workbook", "Office", "Excel: Write Workbook",
fields=(xlsx, FieldSpec("sheet", FieldType.STRING, optional=True,
default="Sheet1")),
description="Write 'rows' (JSON view) to an .xlsx file.",
))
specs.append(CommandSpec(
"AC_read_document", "Office", "Word: Read Document",
fields=(xlsx,),
description="Read a .docx file's paragraphs (needs [office] extra).",
))
specs.append(CommandSpec(
"AC_write_document", "Office", "Word: Write Document",
fields=(xlsx,),
description="Write 'paragraphs' (JSON view) to a .docx file.",
))
specs.append(CommandSpec(
"AC_read_presentation", "Office", "PowerPoint: Read",
fields=(xlsx,),
description="Read a .pptx file's per-slide text (needs [office]).",
))
specs.append(CommandSpec(
"AC_write_presentation", "Office", "PowerPoint: Write",
fields=(xlsx,),
description="Write 'slides' (JSON view) to a .pptx file.",
))


def _add_authoring_specs(specs: List[CommandSpec]) -> None:
Expand Down
43 changes: 43 additions & 0 deletions je_auto_control/utils/executor/action_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -2475,6 +2475,43 @@ def _agent_card(path: Optional[str] = None) -> Dict[str, Any]:
return {"card": build_agent_card()}


def _read_workbook(path: str, sheet: str = "") -> Dict[str, Any]:
"""Adapter: read an .xlsx worksheet into rows."""
from je_auto_control.utils.office import read_workbook
return {"rows": read_workbook(path, sheet=sheet)}


def _write_workbook(path: str, rows: List[Dict[str, Any]],
sheet: str = "Sheet1") -> Dict[str, Any]:
"""Adapter: write rows to an .xlsx file."""
from je_auto_control.utils.office import write_workbook
return {"path": write_workbook(path, rows, sheet=sheet)}


def _read_document(path: str) -> Dict[str, Any]:
"""Adapter: read a .docx file's paragraphs."""
from je_auto_control.utils.office import read_document
return read_document(path)


def _write_document(path: str, paragraphs: List[str]) -> Dict[str, Any]:
"""Adapter: write paragraphs to a .docx file."""
from je_auto_control.utils.office import write_document
return {"path": write_document(path, paragraphs)}


def _read_presentation(path: str) -> Dict[str, Any]:
"""Adapter: read a .pptx file's per-slide text."""
from je_auto_control.utils.office import read_presentation
return read_presentation(path)


def _write_presentation(path: str, slides: List[Any]) -> Dict[str, Any]:
"""Adapter: write slides to a .pptx file."""
from je_auto_control.utils.office import write_presentation
return {"path": write_presentation(path, slides)}


class Executor:
"""
Executor
Expand Down Expand Up @@ -2655,6 +2692,12 @@ def __init__(self):
"AC_skill_search": _skill_search,
"AC_guard_text": _guard_text,
"AC_agent_card": _agent_card,
"AC_read_workbook": _read_workbook,
"AC_write_workbook": _write_workbook,
"AC_read_document": _read_document,
"AC_write_document": _write_document,
"AC_read_presentation": _read_presentation,
"AC_write_presentation": _write_presentation,
"AC_a11y_record_start": _a11y_record_start,
"AC_a11y_record_stop": _a11y_record_stop,
"AC_a11y_record_events": _a11y_record_events,
Expand Down
Loading
Loading