Skip to content
Open
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
202 changes: 202 additions & 0 deletions submissions/word-document-generator-from-template/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
# Word Document Generator from Template

Fill a Microsoft Word template supplied at runtime — **uploaded**, or retrieved
from **SharePoint**, **OneDrive**, or another connector — using **user input**,
approved agent **knowledge sources**, and **results from prior tool or connector
calls**. Works for any document the template defines: **policy, procedure,
report, paper, briefing, SOP, statement of work**, or similar.

The template keeps control of structure, branding, styles, tables, headers, and
footers. A deterministic OOXML engine handles split Word runs, repeating table
rows, and validation while preserving live PAGE / NUMPAGES fields. The skill
writes a **new** DOCX — it never overwrites the original.

## When to use it

| Document kind | Typical template |
| --- | --- |
| Policy | Corporate policy shell (purpose, scope, rules, related docs) |
| Procedure / SOP | Numbered steps, roles, inputs/outputs |
| Report / briefing | Summary, findings table, recommendations |
| Paper | Title, abstract, body headings, references |
| Status pack | Narrative plus rows from Dataverse, SharePoint, or another connector |

Ask the agent to create, draft, or compile the document from that template.

## Before you start

| Input | Why it matters |
| --- | --- |
| Word template (`.docx`) — **required** | Controls layout, placeholders, and branding. May be **uploaded**, or retrieved from **SharePoint**, **OneDrive**, or another connector |
| Document type, title, and purpose | Sets what is being drafted |
| Intended audience | Tones the language |
| Requirements | Anything the template must cover |
| Approved knowledge sources | Grounded content |
| Prior tool / connector results | Records, lists, and fields already retrieved this conversation |
| Output filename | Name of the new DOCX |

Approved sources include knowledge, uploaded files, **and** data returned by
upstream tools or connectors. If a required fact is not in those sources, the
agent writes `Not specified in approved sources` instead of inventing it.

## Ideal Word template structure

The same pattern works for every document type. Use **Word styles** (Heading 1,
Comment thread
nazishqassim marked this conversation as resolved.
Heading 2, Normal) and deterministic `{{placeholders}}` — not finished body
text. The engine supports:

- scalar paths: `{{document.title}}`, `{{sections.purpose}}`;
- repeating rows: `{{findings[].finding}}`, `{{findings[].owner}}`;
- placeholders that Word splits across multiple formatting runs;
- body, table, header, and footer text.

**Do**

- Put branding, page numbers, and classification in the **header / footer**.
- Use **Heading 1** for every major section the finished document must keep.
- Use a **one-row sample table** for anything that repeats (steps, findings, leave types, owners), with the array name followed by `[]`.
- Name placeholders after the field: `{{document.title}}`, `{{sections.<heading>}}`.
- Keep body cells short: `{{sections.purpose}}` or `[Insert from approved sources]`.

**Don’t**

- Bury finished wording in the template (it is not a knowledge source).
- Use floating text boxes or images that hide placeholders.
- Skip headings and rely on bold paragraphs — the agent may miss sections.

### Generic skeleton

**Header:** `Organisation | Classification | {{document.title}}`

**Title (Heading 1):** `{{document.title}}`

**Document control (Heading 2)**

| Field | Placeholder |
| --- | --- |
| Type | `{{document.type}}` |
| Owner | `{{document.owner}}` |
| Version | `{{document.version}}` |
| Status | `{{document.status}}` |
| Audience | `{{document.audience}}` |

**Body** — one Heading 1 per section, placeholder underneath. Name sections
after the template, for example:

| Kind | Typical Heading 1s |
| --- | --- |
| Policy | Purpose, Scope, Policy statements, Responsibilities, Related documents |
| Procedure | Purpose, Scope, Roles, Procedure steps, Exceptions |
| Report | Executive summary, Findings, Analysis, Recommendations |
| Paper | Abstract, Introduction, Discussion, Conclusion, References |

`{{sections.purpose}}`, `{{sections.scope}}`, `{{sections.findings}}`, and so on.

**Repeating table** — keep the header row; leave **one sample data row** to clone:

| Column A | Column B | Column C |
| --- | --- | --- |
| `{{items[].col_a}}` | `{{items[].col_b}}` | `{{items[].col_c}}` |

Rename columns to match the document (`Step` / `Owner` / `System`, or
`Finding` / `Impact` / `Action`, or `Leave type` / `Entitlement` / `Owner`).
Use one array per sample row.

**Footer:** `{{document.version}} | Page X of Y | {{document.status}}`

Insert Page X of Y with Word's live PAGE and NUMPAGES fields, not typed numbers.
The engine changes only the placeholders and verifies those field instructions
remain intact.

The agent fills placeholders from approved sources, **repeats the sample row**
for each JSON array item, and leaves gaps as `Not specified in approved
sources`. Styles, header, footer, and table formatting stay as in the template.

### Example mapping — Leave Policy

A leave policy is only one use of the same skeleton: Heading 1s become Purpose,
Scope, Leave types, Responsibilities; the repeating table columns become
`{{leave_types[].leave_type}}`, `{{leave_types[].entitlement}}`,
`{{leave_types[].owner}}`, `{{leave_types[].evidence}}`.

## How it works

1. Finds the Word template at runtime — from the upload, SharePoint, OneDrive, or the named connector.
2. Runs deterministic inspection to discover exact placeholders, repeating arrays, and Word fields.
3. Pulls facts from approved knowledge, user-supplied files, and prior tool or connector results.
4. Builds JSON that matches **this** template's fields.
5. Fills a new DOCX with split-run and repeating-row support.
6. Validates package integrity, unresolved placeholders, and live Word fields.
7. Returns the new DOCX and a machine-generated summary.

## Quick test

The bundled report template intentionally contains split-run placeholders, a
repeating findings row, branding, two sections, and live PAGE / NUMPAGES fields.

```bash
# 1. Discover the template contract
python scripts/docx_template.py inspect assets/sample-template.docx \
--output sample-manifest.json

# 2. Fill a new file
python scripts/docx_template.py fill \
assets/sample-template.docx assets/sample-data.json sample-output.docx \
--summary sample-summary.json

# 3. Verify there are no raw tokens and live fields survived
python scripts/docx_template.py validate sample-output.docx \
--template assets/sample-template.docx --output sample-validation.json
```

Expected: each command exits `0`, the findings table has three data rows, no
`{{...}}` remains, and validation reports
`"field_signature_preserved": true`.

For the full grammar and limits, see
[`references/placeholder-contract.md`](references/placeholder-contract.md).

### Bundled files

| File | Purpose |
| --- | --- |
| `scripts/docx_template.py` | Production inspect / fill / validate engine |
| `assets/sample-template.docx` | Realistic report template with split runs and live fields |
| `assets/sample-data.json` | Template-shaped example data |
| `assets/sample-template.manifest.json` | Expected inspection result |
| `references/placeholder-contract.md` | Exact grammar, supported scope, and limits |
| `scripts/test_docx_template.py` | Automated regression suite |
| `scripts/build_sample_template.py` | Rebuild the sample template |

## Example requests

> Use the Leave Policy template in SharePoint (`Policies/Templates/Leave-Policy.docx`).
> Draft version 0.1 for internal staff from approved HR knowledge.
> Save as `Leave-Policy-v0.1.docx`.

> Fill the incident-response **procedure** template in OneDrive.
> Use the approved ops playbook for the steps. Save as `IR-Procedure-v2.docx`.

> Get this quarter's accounts from Dataverse, then fill the **status report**
> template. Connector rows go in the findings table; knowledge base for the narrative.
> Save as `Q3-Account-Status.docx`.

The agent returns the completed Word file plus a summary of what was filled,
what was missing, and which sources were used — including connector names.

## Good to know

- Output is a **draft** until a human reviews and approves it.
- Connector and tool results from earlier in the conversation are valid sources; the agent should not re-fetch them unless they are missing.
- Unsupported statements are marked for review, not presented as fact.
- The template is a prerequisite. Attach it, or point the agent at SharePoint, OneDrive, or another connector that can fetch the `.docx`.
- The template is not treated as a knowledge source unless you say so.
- Sections are not added or removed unless you explicitly ask.
- The original template in SharePoint, OneDrive, or the upload is never overwritten.
- Supported replacement content is plain text (including line breaks). Rich
HTML/Markdown, nested repeating arrays, and placeholders spanning paragraphs
are intentionally rejected or out of scope.
- Filling fails loudly on malformed tokens, invalid JSON shapes, remaining
placeholders, corrupt DOCX packages, or changed Word field instructions.
- If no `.docx` template is available, generation stops with:
`The required Word template was not supplied or could not be accessed.`
188 changes: 188 additions & 0 deletions submissions/word-document-generator-from-template/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
---
name: word-document-generator-from-template
description: Generates a complete Word document from a Word template supplied at runtime (uploaded, or retrieved from SharePoint, OneDrive, or another connector) plus user input, approved knowledge sources, and prior tool or connector results. Use when a user asks to create, draft, or compile any document from a template — policy, procedure, report, paper, briefing, SOP, or similar.
---
# Word Document Generator from Template

## Purpose

Generate a complete Microsoft Word document of **any type the template defines**
(policy, procedure, report, paper, briefing, SOP, statement of work, or similar) using:

- a Word template supplied at runtime (uploaded by the user, or retrieved from SharePoint, OneDrive, or another connector);
- information provided by the user;
- approved agent knowledge sources;
- files supplied with the request; and
- information retrieved from prior tool or connector calls in the same conversation (for example Dataverse, SharePoint, CRM, or any Copilot Studio action).

The runtime template controls document type, structure, formatting, headings,
tables, headers, footers, and branding. Adapt JSON keys to **that** template —
do not assume a fixed outline. Use the bundled deterministic engine for DOCX
inspection, filling, and validation; do not implement ad-hoc run replacement.

## Required inputs

Before generating the document, identify:

- the Word template to use, and where it comes from (upload, SharePoint, OneDrive, or another location);
- the document type, title, and purpose;
- the intended audience;
- any user-provided requirements;
- the approved knowledge sources to use;
- any relevant results from prior tool or connector calls; and
- the required output filename.

If required information is unavailable, use:

`Not specified in approved sources`

Do not invent facts, dates, owners, approvals, obligations, or organizational information.

## Instructions

1. Locate the runtime `.docx` template. Use the uploaded file, or retrieve the
user-identified SharePoint / OneDrive / connector item into the working
directory. Stop with the message under **Template handling** if unavailable.
2. Inspect it before writing content:

```bash
python scripts/docx_template.py inspect template.docx --output manifest.json
```

Read the manifest's exact scalar placeholders, repeating arrays, parts, and
live Word fields. If inspection rejects the template, report the error; do
not guess at its schema.
3. Retrieve relevant information from approved knowledge, user files, and prior
tool/connector results already in the conversation. Prefer connector-returned
records, dates, owners, and IDs over restating them from memory.
4. Generate long documents section by section. Build a JSON object whose paths
exactly match the manifest. Use arrays for repeating table rows. Use
`Not specified in approved sources` for unsupported facts.
5. Validate the JSON conceptually: all required template fields are represented,
claims are grounded, and each array item supplies the expected row fields.
6. Fill a **new** file with the deterministic engine:

```bash
python scripts/docx_template.py fill template.docx data.json output.docx \
--summary fill-summary.json
```

Never set `output.docx` to the template path.
7. Validate package integrity, unresolved tokens, and live Word fields:

```bash
python scripts/docx_template.py validate output.docx \
--template template.docx --output validation.json
```

Do not return a DOCX unless both commands succeed.
8. Return the completed DOCX plus a short generation summary: output filename,
document type, sources used, filled/defaulted fields, repeated-row counts,
and validation status.

## Generation rules

- Follow the runtime template's outline. JSON keys must match the inspection
manifest, not a hard-coded schema.
- Use only information from approved knowledge sources, user-supplied files, or prior tool/connector results. Do not invent facts that those sources do not contain.
- Treat prior tool and connector outputs as approved sources. Record the tool or connector name in `source_ids` (for example `Dataverse:accounts`, `SharePoint:policy-library`).
- Generate long documents section by section rather than in one response.
- Keep the structured JSON as the intermediate source of truth.
- Use clear, professional, organization-appropriate language for the stated audience.
- Preserve mandatory wording found in approved sources.
- Do not treat the template file as a knowledge source unless instructed.
- Do not add new sections unless required to complete the template.
- Do not remove sections from the template without an explicit instruction.
- Record the sources used for each major section when source information is available.
- Do not replace runs manually or clear footer/header paragraphs. The script
handles split-run tokens and preserves PAGE, NUMPAGES, TOC, REF, and other
live Word fields.

## Template handling

A Word template (`.docx`) is a **prerequisite**. It is supplied at runtime from one of:

- a file **uploaded** with the request;
- **SharePoint** (document library, folder, or site);
- **OneDrive**; or
- another connector or prior tool call that returns a Word file.

Resolve the template in this order:

1. Use the template the user named (filename, SharePoint/OneDrive path, or library item).
2. If it is already in the runtime working directory, use that `.docx`.
3. If it is not local, retrieve it from SharePoint, OneDrive, or the identified connector.
4. If more than one Word file is available, select the one identified in the user request.

Never overwrite the original template in SharePoint, OneDrive, or local storage. Always save a **new** DOCX.

If the required template cannot be found or retrieved, stop document generation and report:

'The required Word template was not supplied or could not be accessed.'

## Template contract

Use `{{path.to.value}}` for scalar text and `{{items[].field}}` in one sample
table row for repetition. Tokens may be split across Word runs; the engine
matches their visible paragraph text. It fills the main document, tables,
headers, and footers while preserving live Word fields.

Read [`references/placeholder-contract.md`](references/placeholder-contract.md)
for the exact grammar, supported scope, limits, and troubleshooting.

## Structured JSON

Create JSON that reflects the **runtime template**. Use:

- `document` — title, type, owner, version, status, audience, and any other metadata fields on the cover or control table;
- `sections` — one object per Heading 1 / Heading 2, keyed by a slug of that heading;
- `items` (or a name taken from the table, e.g. `leave_types`, `findings`, `steps`) — arrays for repeating tables or content blocks;
- `sources` — identifiers for knowledge, files, and connectors.

Example shape (field names change to match the template):

```json
{
"document": {
"title": "Quarterly Operations Report",
"type": "Report",
"owner": "Operations",
"version": "1.0",
"status": "Draft",
"audience": "Leadership team"
},
"sections": {
"executive_summary": "Generated section content",
"purpose": "Generated section content"
},
"findings": [
{
"finding": "Generated finding",
"impact": "Generated impact",
"owner": "Action owner"
}
],
"sources": [
{
"source_id": "SRC-001",
"title": "Approved source",
"type": "knowledge | file | connector"
}
]
}
```

A Leave Policy template might use `leave_types`; a procedure might use `steps`;
a report might use `findings` or connector rows. Always use the array names
reported by template inspection.

## Requirements

The engine uses Python's standard library plus `lxml`, preinstalled in the
Copilot Studio sandbox. The sample-template builder and tests additionally use
preinstalled `python-docx` and Pillow. No network service or `pip install` is
needed in Copilot Studio.

## Quality and safety

The generated document is a draft until reviewed and approved. If a statement cannot be supported by approved knowledge, a user-supplied file, or a prior tool/connector result, do not present it as fact. Mark it for human review.
Loading