kaos-office
Part of Kelvin Agentic OS (KAOS) — open agentic infrastructure for legal work, built by 273 Ventures. See the full KAOS package map for the rest of the stack.
kaos-office is the Office-document layer of KAOS — it turns Microsoft
Office files (.docx, .pptx, .xlsx) into typed
kaos-content AST models with
provenance, and turns those models back into round-trip-fidelity Office
files. DOCX and PPTX produce ContentDocument (Block / Inline flow
content with headings, paragraphs, lists, tables, footnotes,
annotations, tracked changes, and per-section page setup); XLSX produces
TabularDocument (typed columns over a 13-type ColumnType system, one
Table per sheet, formulas and merged ranges preserved as metadata).
The package also ships 18 read / write MCP tools and a 13-subcommand
admin CLI for agentic workflows.
The base install is intentionally small — four runtime dependencies
(kaos-content[markdown], kaos-core, lxml, python-pptx) and no
compiled native code beyond the lxml wheel. DOCX and XLSX read /
write paths use lxml directly so they stay symmetric; PPTX read /
write goes through python-pptx (MIT) — both parse_pptx() and
write_pptx() work without any extras. [pptx] is now a no-op alias
kept for backwards compatibility. [xlsx] aggregates
python-calamine (MIT, Rust — 7-28× faster XLSX read) and openpyxl
(MIT, formula extraction) — pick [xlsx-calamine] or
[xlsx-formulas] individually if you want only one. We do not and
will not depend on AGPL or GPL libraries.
Install
uv add "kaos-office>=0.1.0"
# or
pip install "kaos-office>=0.1.0"
# PPTX writer (python-pptx)
uv add 'kaos-office[pptx]>=0.1.0'
# Calamine XLSX fast-path + openpyxl formula extraction
uv add 'kaos-office[xlsx]>=0.1.0'
# BM25 sentence-level search via kaos-nlp-core
uv add 'kaos-office[nlp]>=0.1.0'
kaos-office requires Python 3.13 or newer (3.14 is supported).
The package is pure Python — the only native code is the lxml wheel,
which has prebuilt wheels for Linux, macOS, and Windows on x86_64 and
arm64.
Quick start
Read a DOCX into the AST, render it as markdown, and search it; then read an XLSX as a typed tabular document:
from kaos_office import (
extract_to_markdown,
parse_docx,
parse_pptx,
search_document,
)
from kaos_office.xlsx import list_sheets, parse_xlsx
# DOCX → ContentDocument with Block/Inline + provenance on every node
doc = parse_docx("contract.docx")
print(len(doc.body), "top-level blocks")
print(doc.metadata.title, doc.metadata.source.uri)
# Same shape for PPTX (each slide becomes a Div(classes="slide"))
deck = parse_pptx("brief.pptx")
print(deck.metadata.extra.get("slide_count"), "slides")
# AST-grounded search — paragraph-level by default
hits = search_document(doc, "indemnification", top_k=5)
for hit in hits.results:
print(f"score={hit.score:.2f} :: {hit.text[:80]}")
# XLSX → TabularDocument (one Table per sheet, typed columns)
tab = parse_xlsx("report.xlsx")
for table in tab.tables:
print(f"{table.name}: {table.row_count} rows × {len(table.columns)} cols")
print(list_sheets("report.xlsx")) # cheap workbook metadata, no parse
# Format-agnostic shortcut: any of the three → markdown
print(extract_to_markdown("contract.docx")[:200])
Every node in the returned ContentDocument carries a Provenance
(source URI, page or slide number, char span, extractor name) so
downstream consumers — citation verifiers, redaction tooling, labelers
— can ground answers back to the original file.
Concepts
The package is a thin, typed surface over the OOXML wire format. The most important entries:
| Concept | What it is |
|---|---|
parse_docx(path, *, track_changes=False, image_src_builder=...) |
DOCX reader. Returns a ContentDocument with paragraphs, headings, lists, tables, footnotes, comments (as annotations), hyperlinks, embedded images, and per-section page setup. track_changes=True preserves w:ins / w:del / w:moveFrom / w:moveTo as Span / Div with rev-* classes plus TRACKED_CHANGE annotations. |
parse_pptx(path) |
PPTX reader. Each slide → Div(classes="slide", slide_number=N). Uses python-pptx for shape traversal and falls back to OPC/lxml for SmartArt text — the only Python tool that does. Charts linearize to Tables with category + series columns. Speaker notes land as Div(classes="speaker-notes"). |
parse_xlsx(path, *, sheets=None, max_rows=None, header_row=0, include_formulas=False, engine="native") |
XLSX reader. Returns a TabularDocument. Default engine="native" is pure lxml; engine="calamine" switches to the Rust fast-path ([xlsx-calamine]). include_formulas=True extracts cell formulas via openpyxl ([xlsx-formulas]). |
write_docx(doc, path) / write_docx_bytes(doc) |
DOCX writer (lxml). Round-trips the DOCX feature surface: paragraphs / headings, bullet + ordered lists with proper numbering.xml, tables with grid spans, hyperlinks (with proper rels), footnotes, endnotes, comments, headers, footers, page setup, multi-section documents, embedded images (data: / file:// URIs), and SDT / content-control wrappers. |
compare_docx(original, revised, *, author="Reviewer", detect_moves=True) / write_redline(original, revised, output, ...) |
Redline two DOCX files. compare_docx returns a ContentDocument whose differences are tracked changes (word-level edits inside changed paragraphs, block insert/delete, and move detection); write_redline writes it to a .docx Word opens with native tracked changes. Built on kaos_content.compare_documents — accepting all changes reproduces the revised document, rejecting all reproduces the original. The CLI exposes it as kaos-office redline ORIGINAL REVISED OUTPUT. |
write_pptx(doc, path, *, template=None, overflow="warn"/"autofit"/"extend") |
PPTX writer (python-pptx, lazy-imported with [pptx] install hint at call time). Auto-segments at Heading(depth=1). overflow controls how text that may not fit a shape is handled — "warn" (default) emits a logger warning, "autofit" shrinks the font, "extend" grows the shape. |
write_xlsx(doc, path, *, bold_headers=True, auto_width=True, freeze_header=True) / write_xlsx_bytes(doc) |
XLSX writer (lxml — no extras needed). Native SpreadsheetML output with proper date formats, money formats, percentage / float / integer formats per ColumnType, auto-sized columns, bold header row, and frozen panes. |
search_document(doc, query, *, top_k=10, level="paragraph") |
Re-exported from kaos-content. AST-grounded ranked search returning SearchResults with total_matches / has_more for pagination. level="sentence" requires the [nlp] extra. |
extract_to_markdown(path, **kwargs) |
Format-agnostic convenience wrapper. Dispatches by extension to parse_docx + serialize_markdown, parse_pptx + serialize_markdown, or parse_xlsx + serialize_tabular_markdown. |
| 18 MCP tools | ParseDocxTool, GetDocxTextTool, GetDocxMarkdownTool, DocxMetadataTool, SearchDocxTool (5 DOCX) · ParsePptxTool, ListSlidesTool, GetSlideTool, GetSlideNotesTool, SearchPptxTool (5 PPTX) · ParseXlsxTool, ListSheetsXlsxTool, GetSheetXlsxTool, XlsxMetadataTool (4 XLSX) · WriteDocxTool, WritePptxTool, WriteXlsxTool, CompareDocxTool (4 writers — the last compares two DOCX files into a tracked-changes redline). All readers are readOnly + idempotent + non-destructive + non-open-world; writers refuse silent overwrites unless force=true. Register with register_office_tools(runtime). |
Errors (KaosOfficeError, DocxExtractionError, PptxExtractionError, XlsxExtractionError) |
Dedicated exception hierarchy. MCP tools translate these into ToolResult.create_error() with the documented three-part recovery hint (what / how to fix / alternative tool). |
CLI
kaos-office ships two entry-point scripts. Every structured command
on the admin CLI supports --json for machine-readable output piped to
other agents:
kaos-office --help # admin CLI
kaos-office-serve --help # MCP server
# DOCX
kaos-office extract contract.docx -f markdown # AST → markdown / text / json / html
kaos-office search contract.docx "indemnification" # AST-grounded ranked search
kaos-office metadata contract.docx --json # title, author, page setup, sections
# PPTX
kaos-office pptx-extract brief.pptx -f markdown
kaos-office pptx-slides brief.pptx --json # slide inventory (number, title, layout)
kaos-office pptx-slide brief.pptx 3 # text from a single slide (1-based)
# XLSX
kaos-office xlsx-extract report.xlsx -f markdown # tabular markdown
kaos-office xlsx-sheets report.xlsx --json # sheet names + dimensions
kaos-office xlsx-sheet report.xlsx Revenue # one sheet as TSV
# Writers (JSON file or '-' for stdin)
kaos-office write-docx body.json out.docx --force
kaos-office write-pptx body.json out.pptx --template brand.pptx
kaos-office write-xlsx tabular.json out.xlsx
kaos-office-serve # stdio (Claude Code / Desktop)
kaos-office-serve --http --port 8000 # streamable HTTP
The admin CLI uses 1-based slide / page numbers (consistent with how
the file opens in any viewer) and translates internally to the
0-based indices the Python API uses. kaos-office-serve exposes the
18 MCP tools listed in Concepts above.
Compatibility & status
| Aspect | |
|---|---|
| Python | 3.13, 3.14 |
| OS | Linux, macOS, Windows (pure-Python wheel; the only native code is the lxml wheel) |
| Maturity | 0.1.0 GA. The public API is documented in kaos_office.__all__. |
| Stability policy | Pre-1.0: minor bumps may change behaviour. Every change is documented in CHANGELOG.md. The MCP tool surface (kaos-office-* names) and the KAOS_OFFICE_* environment-variable namespace are public API and follow the same policy. |
| Test coverage | 492 unit tests plus a 144-test integration tier covering DOCX / PPTX / XLSX round-trip fidelity against real-world fixtures. Bounded unit gate (pytest tests/unit -q --no-cov) finishes in ~30s. |
| Type checker | Validated with ty, Astral's Python type checker. |
Documentation
Per-package reference: see in-tree docstrings and CHANGELOG.md.
Cross-cutting KAOS guides (agentic patterns, persona presets, settings
policy, citations, MCP data flow, migration to 0.1.0 GA) live in
kaos-modules/docs/guides/.
Companion packages
kaos-office is one of the packages in the
Kelvin Agentic OS. The broader stack:
| Package | Layer | What it does |
|---|---|---|
kaos-core |
Core | Foundational runtime, MCP-native types, registries, execution engine, VFS |
kaos-content |
Core | Typed document AST: Block/Inline, provenance, views |
kaos-mcp |
Bridge | FastMCP server, kaos management CLI, MCP resource templates |
kaos-pdf |
Extraction | PDF → AST with provenance |
kaos-web |
Extraction | Web extraction, browser automation, search, domain intelligence |
kaos-office |
Extraction | DOCX / PPTX / XLSX readers + writers to AST |
kaos-tabular |
Extraction | DuckDB-powered SQL analytics |
kaos-source |
Data | Government + financial data connectors (Federal Register, eCFR, EDGAR, GovInfo, PACER, GLEIF) |
kaos-llm-client |
LLM | Multi-provider LLM transport |
kaos-llm-core |
LLM | Typed LLM programming (Signatures, Programs, Optimizers) |
kaos-nlp-core |
Primitives (Rust) | High-performance NLP primitives |
kaos-nlp-transformers |
ML | Dense embeddings + retrieval |
kaos-graph |
Primitives (Rust) | Graph algorithms + RDF/SPARQL |
kaos-ml-core |
Primitives (Rust) | Classical ML on the document AST |
kaos-citations |
Legal | Legal citation extraction, resolution, verification |
kaos-agents |
Agentic | Agent runtime, memory, recipes |
kaos-reference |
Sample | Reference module for module authors |
Packages depend on kaos-core; everything else is opt-in. Mix and match the
ones you need.
Development
git clone https://github.com/273v/kaos-office
cd kaos-office
uv sync --group dev
Install pre-commit hooks (recommended — they run the same checks as CI on every commit, scoped to staged files):
uvx pre-commit install
uvx pre-commit run --all-files # one-time full sweep
Manual QA commands (the same set CI runs):
uv run ruff format --check kaos_office tests
uv run ruff check kaos_office tests
uv run ty check kaos_office tests
uv run pytest tests/unit -q --no-cov
Build from source
uv build
uv pip install dist/*.whl
python -c "import kaos_office; print(kaos_office.__version__)" # smoke import
Contributing
Issues and pull requests are welcome. See CONTRIBUTING.md
for setup, quality gates, pull request expectations, and engineering
standards. By contributing you agree to follow the
project conduct expectations and certify the
Developer Certificate of Origin v1.1 —
sign every commit with git commit -s. Please open an issue before starting
on a non-trivial change so we can align on scope.
Security
For security issues, please do not file a public issue. Report privately via GitHub Private Vulnerability Reporting or email security@273ventures.com. See SECURITY.md for the full disclosure policy.
License
Apache License 2.0 — see LICENSE and NOTICE.
Copyright 2026 273 Ventures LLC. Built for kelvin.legal.
Release files for kaos-office 0.1.7
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| kaos_office-0.1.7.tar.gz | 133.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| kaos_office-0.1.7-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 275.1 kB
Release files / kaos_office-0.1.7.tar.gz
| Download URL | kaos_office-0.1.7.tar.gz |
|---|---|
| Size | 133.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c297a65c2c1ec6476855ce4fe12d4355b640198621c756f121b56aad89793821
|
|
BLAKE2b-256 checksum How to use checksums |
c660a3c115a6916ae46b757a221f75924802ba1d8ce30ad4abf3f8ae029d28f5
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency logRelease files / kaos_office-0.1.7-py3-none-any.whl
| Download URL | kaos_office-0.1.7-py3-none-any.whl |
|---|---|
| Size | 141.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f3e890416978b7684c7b3eee943c97064786fc02f84b6cf998dd111d582ecf0c
|
|
BLAKE2b-256 checksum How to use checksums |
2ee23c4a6108a953779ff80430c23fe4a7826bf20ee7d7c6c3635bc3f8161c4e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 23, 2026.
Transparency log