-
Notifications
You must be signed in to change notification settings - Fork 75
Add word document generator from template #284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Nazish (nazishqassim)
wants to merge
9
commits into
microsoft:main
Choose a base branch
from
nazishqassim:add-word-document-generator-from-template
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
fc6f8f5
Fix validation logic for app registration and improve error handling
nazishqassim f3ac5ac
Enhance Word Document Generator skill to utilize prior tool and conne…
nazishqassim 2f0b127
Update Word Document Generator skill to clarify template sourcing and…
nazishqassim c16b962
Update Word Document Generator to reflect new Leave Policy template
nazishqassim 2bf2dd0
Enhance README for Word Document Generator with ideal template structure
nazishqassim 2a89b96
Update Word Document Generator skill to enhance document type flexibi…
nazishqassim 70dfc54
Merge branch 'main' into add-word-document-generator-from-template
nazishqassim 720960c
Enhance Word Document Generator: Update instructions for template han…
nazishqassim 5becf3f
Refactor Word Document Generator: Improve template processing and val…
nazishqassim File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
202 changes: 202 additions & 0 deletions
202
submissions/word-document-generator-from-template/README.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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, | ||
| 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
188
submissions/word-document-generator-from-template/SKILL.md
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.