altr-oss 0.2.0__tar.gz
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.
- altr_oss-0.2.0/.github/workflows/ci.yml +31 -0
- altr_oss-0.2.0/.github/workflows/release.yml +43 -0
- altr_oss-0.2.0/.gitignore +17 -0
- altr_oss-0.2.0/CONTRIBUTING.md +54 -0
- altr_oss-0.2.0/LICENSE +21 -0
- altr_oss-0.2.0/PKG-INFO +203 -0
- altr_oss-0.2.0/README.md +155 -0
- altr_oss-0.2.0/examples/budget.json +28 -0
- altr_oss-0.2.0/examples/onboarding-doc.json +26 -0
- altr_oss-0.2.0/examples/pitch-deck.json +33 -0
- altr_oss-0.2.0/pyproject.toml +43 -0
- altr_oss-0.2.0/src/altr/__init__.py +24 -0
- altr_oss-0.2.0/src/altr/agent.py +111 -0
- altr_oss-0.2.0/src/altr/cli.py +104 -0
- altr_oss-0.2.0/src/altr/markdown.py +103 -0
- altr_oss-0.2.0/src/altr/pdf.py +39 -0
- altr_oss-0.2.0/src/altr/prompts.py +28 -0
- altr_oss-0.2.0/src/altr/renderers/__init__.py +25 -0
- altr_oss-0.2.0/src/altr/renderers/docx.py +85 -0
- altr_oss-0.2.0/src/altr/renderers/pptx.py +91 -0
- altr_oss-0.2.0/src/altr/renderers/xlsx.py +70 -0
- altr_oss-0.2.0/src/altr/schemas.py +195 -0
- altr_oss-0.2.0/src/altr/tools.py +99 -0
- altr_oss-0.2.0/tests/test_agent.py +95 -0
- altr_oss-0.2.0/tests/test_features.py +175 -0
- altr_oss-0.2.0/tests/test_markdown.py +55 -0
- altr_oss-0.2.0/tests/test_renderers.py +92 -0
- altr_oss-0.2.0/tests/test_tools.py +43 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: read
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
test:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
matrix:
|
|
16
|
+
python-version: ["3.10", "3.12"]
|
|
17
|
+
steps:
|
|
18
|
+
- uses: actions/checkout@v4
|
|
19
|
+
- uses: actions/setup-python@v5
|
|
20
|
+
with:
|
|
21
|
+
python-version: ${{ matrix.python-version }}
|
|
22
|
+
- name: Install
|
|
23
|
+
run: pip install -e ".[dev]"
|
|
24
|
+
- name: Test
|
|
25
|
+
run: pytest -q
|
|
26
|
+
- name: Smoke-test offline rendering
|
|
27
|
+
run: |
|
|
28
|
+
altr render document examples/onboarding-doc.json --out smoke
|
|
29
|
+
altr render spreadsheet examples/budget.json --out smoke
|
|
30
|
+
altr render presentation examples/pitch-deck.json --out smoke
|
|
31
|
+
ls -l smoke
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
name: Release to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
push:
|
|
7
|
+
tags: ["v*"]
|
|
8
|
+
workflow_dispatch:
|
|
9
|
+
|
|
10
|
+
permissions:
|
|
11
|
+
contents: read
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- name: Build sdist and wheel
|
|
22
|
+
run: |
|
|
23
|
+
pip install build
|
|
24
|
+
python -m build
|
|
25
|
+
- uses: actions/upload-artifact@v4
|
|
26
|
+
with:
|
|
27
|
+
name: dist
|
|
28
|
+
path: dist/
|
|
29
|
+
|
|
30
|
+
publish:
|
|
31
|
+
needs: build
|
|
32
|
+
runs-on: ubuntu-latest
|
|
33
|
+
environment: pypi
|
|
34
|
+
permissions:
|
|
35
|
+
id-token: write # PyPI trusted publishing
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/download-artifact@v4
|
|
38
|
+
with:
|
|
39
|
+
name: dist
|
|
40
|
+
path: dist/
|
|
41
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
42
|
+
with:
|
|
43
|
+
skip-existing: true # tag push + release publish must not double-upload
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Contributing to altr
|
|
2
|
+
|
|
3
|
+
Thanks for your interest! Bug reports, new block types, renderer improvements,
|
|
4
|
+
and docs are all welcome.
|
|
5
|
+
|
|
6
|
+
## Development setup
|
|
7
|
+
|
|
8
|
+
You need Python 3.10+.
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
git clone https://github.com/PasinduSuraweera/altr-oss
|
|
12
|
+
cd altr-oss
|
|
13
|
+
python -m venv .venv && source .venv/bin/activate
|
|
14
|
+
pip install -e ".[dev]"
|
|
15
|
+
pytest
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Try the offline renderer without an API key:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
altr render presentation examples/pitch-deck.json
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Guidelines
|
|
25
|
+
|
|
26
|
+
- Keep PRs focused: one change per PR.
|
|
27
|
+
- Every schema or renderer change needs a test that re-opens the generated
|
|
28
|
+
file and asserts on its contents (see `tests/test_renderers.py`).
|
|
29
|
+
- Field descriptions in `schemas.py` are model-facing prompt text - keep them
|
|
30
|
+
short, concrete, and example-driven.
|
|
31
|
+
- `dispatch()` must never raise on bad model input; return
|
|
32
|
+
`{"ok": False, "error": ...}` so the model can self-correct.
|
|
33
|
+
|
|
34
|
+
## Releasing to PyPI (maintainers)
|
|
35
|
+
|
|
36
|
+
Releases publish automatically via PyPI trusted publishing - no API tokens.
|
|
37
|
+
One-time setup, done once by the repo owner:
|
|
38
|
+
|
|
39
|
+
1. On pypi.org: Account -> Publishing -> add a "pending publisher" for project
|
|
40
|
+
`altr-oss` (PyPI rejects `altr` as too similar to an existing project),
|
|
41
|
+
owner `PasinduSuraweera`, repo `altr-oss`, workflow `release.yml`,
|
|
42
|
+
environment `pypi`.
|
|
43
|
+
2. On GitHub: repo Settings -> Environments -> create an environment named
|
|
44
|
+
`pypi`.
|
|
45
|
+
|
|
46
|
+
Then to ship a release: bump `version` in `pyproject.toml`, tag (e.g.
|
|
47
|
+
`v0.2.0`), and publish a GitHub release - the workflow builds and uploads to
|
|
48
|
+
PyPI.
|
|
49
|
+
|
|
50
|
+
## Proposing features
|
|
51
|
+
|
|
52
|
+
Open an issue first for anything beyond a small fix (new document features,
|
|
53
|
+
template support, new output formats) - a short design discussion up front
|
|
54
|
+
saves rework.
|
altr_oss-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Pasindu Suraweera
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
altr_oss-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: altr-oss
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Open source doc / excel / ppt skills for LLMs - Groq, Ollama, vLLM, any OpenAI-compatible endpoint.
|
|
5
|
+
Project-URL: Homepage, https://github.com/PasinduSuraweera/altr-oss
|
|
6
|
+
Author: Pasindu Suraweera
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026 Pasindu Suraweera
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Keywords: docx,gpt-oss,groq,llm,pptx,skills,tool-calling,xlsx
|
|
30
|
+
Classifier: Development Status :: 4 - Beta
|
|
31
|
+
Classifier: Intended Audience :: Developers
|
|
32
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
33
|
+
Classifier: Programming Language :: Python :: 3
|
|
34
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
35
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
36
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
37
|
+
Classifier: Topic :: Office/Business :: Office Suites
|
|
38
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
39
|
+
Requires-Python: >=3.10
|
|
40
|
+
Requires-Dist: openai>=1.40
|
|
41
|
+
Requires-Dist: openpyxl>=3.1
|
|
42
|
+
Requires-Dist: pydantic>=2.7
|
|
43
|
+
Requires-Dist: python-docx>=1.1
|
|
44
|
+
Requires-Dist: python-pptx>=1.0
|
|
45
|
+
Provides-Extra: dev
|
|
46
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
47
|
+
Description-Content-Type: text/markdown
|
|
48
|
+
|
|
49
|
+
# altr
|
|
50
|
+
|
|
51
|
+
> Open source doc / excel / ppt skills for LLMs.
|
|
52
|
+
|
|
53
|
+
[](https://github.com/PasinduSuraweera/altr-oss/actions/workflows/ci.yml)
|
|
54
|
+
[](LICENSE)
|
|
55
|
+
[](pyproject.toml)
|
|
56
|
+
|
|
57
|
+
Claude has document skills. ChatGPT has them. **Open-weight models don't.**
|
|
58
|
+
Point `gpt-oss-120b` on Groq (or any model behind an OpenAI-compatible API) at
|
|
59
|
+
altr and it gains three tools it can call to produce real files:
|
|
60
|
+
|
|
61
|
+
| Tool | Output | Good for |
|
|
62
|
+
| --------------------- | ------- | ------------------------------------------ |
|
|
63
|
+
| `create_document` | `.docx` | reports, guides, letters, meeting notes |
|
|
64
|
+
| `create_spreadsheet` | `.xlsx` | budgets, trackers, datasets - with formulas |
|
|
65
|
+
| `create_presentation` | `.pptx` | pitch decks, talks - with speaker notes |
|
|
66
|
+
|
|
67
|
+
The model sends structured JSON through standard tool calling; altr
|
|
68
|
+
validates it (Pydantic) and renders it (`python-docx`, `openpyxl`,
|
|
69
|
+
`python-pptx`). Renderer errors are fed back to the model so it can correct
|
|
70
|
+
itself. No code execution, no sandboxes - the model can only emit document
|
|
71
|
+
content.
|
|
72
|
+
|
|
73
|
+
## Install
|
|
74
|
+
|
|
75
|
+
```sh
|
|
76
|
+
pip install altr-oss
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The PyPI distribution is `altr-oss`; the import and the CLI command are both
|
|
80
|
+
plain `altr`.
|
|
81
|
+
|
|
82
|
+
Or straight from the repo:
|
|
83
|
+
|
|
84
|
+
```sh
|
|
85
|
+
pip install git+https://github.com/PasinduSuraweera/altr-oss
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Quickstart (CLI)
|
|
89
|
+
|
|
90
|
+
```sh
|
|
91
|
+
export GROQ_API_KEY=gsk_...
|
|
92
|
+
|
|
93
|
+
altr make "Create a 6-slide pitch deck for a solar-powered drone startup"
|
|
94
|
+
altr make "Make a 12-month SaaS budget spreadsheet with formula totals"
|
|
95
|
+
altr make "Write a 2-page onboarding doc for new backend engineers"
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Files land in `./output`. Works with any OpenAI-compatible server:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
# Groq (default)
|
|
102
|
+
altr make "..." --model openai/gpt-oss-120b
|
|
103
|
+
|
|
104
|
+
# Ollama, fully local
|
|
105
|
+
altr make "..." --base-url http://localhost:11434/v1 --model llama3.3 --api-key ollama
|
|
106
|
+
|
|
107
|
+
# vLLM / LM Studio / anything else that speaks chat completions
|
|
108
|
+
altr make "..." --base-url http://localhost:8000/v1 --model my-model
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Render a JSON spec directly, no model involved (great for testing):
|
|
112
|
+
|
|
113
|
+
```sh
|
|
114
|
+
altr render presentation examples/pitch-deck.json
|
|
115
|
+
altr render spreadsheet examples/budget.json
|
|
116
|
+
altr render document examples/onboarding-doc.json
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## Use it as a library
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from altr import OfficeAgent
|
|
123
|
+
|
|
124
|
+
agent = OfficeAgent(model="openai/gpt-oss-120b", out_dir="out")
|
|
125
|
+
result = agent.run("Create a quarterly report with a KPI table")
|
|
126
|
+
print(result.files) # [PosixPath('out/quarterly-report.docx')]
|
|
127
|
+
print(result.reply) # the model's final message
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## Use it as a skill in your own agent
|
|
131
|
+
|
|
132
|
+
Already have an agent loop? Take just the tools:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from altr import SYSTEM_PROMPT, get_tools, dispatch
|
|
136
|
+
|
|
137
|
+
response = client.chat.completions.create(
|
|
138
|
+
model="openai/gpt-oss-120b",
|
|
139
|
+
messages=[{"role": "system", "content": SYSTEM_PROMPT}, ...],
|
|
140
|
+
tools=get_tools(), # OpenAI-format tool definitions
|
|
141
|
+
)
|
|
142
|
+
|
|
143
|
+
for call in response.choices[0].message.tool_calls:
|
|
144
|
+
result = dispatch(call.function.name, call.function.arguments, out_dir="out")
|
|
145
|
+
# {"ok": True, "file": "out/report.docx"} - or {"ok": False, "error": ...}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
`dispatch` never raises on bad model output - validation and render errors come
|
|
149
|
+
back as data you can hand to the model for self-correction.
|
|
150
|
+
|
|
151
|
+
## What the model can express
|
|
152
|
+
|
|
153
|
+
- **Documents**: headings (9 levels), paragraphs with inline
|
|
154
|
+
**bold**/*italic*/`code`, bullet & numbered lists, tables with bold headers,
|
|
155
|
+
images with captions, whole markdown blocks, page breaks.
|
|
156
|
+
- **Spreadsheets**: multiple worksheets, bold header rows, column widths,
|
|
157
|
+
frozen header rows, live Excel formulas (`=SUM(B2:B10)`), and bar/line/pie
|
|
158
|
+
charts built from the sheet's data.
|
|
159
|
+
- **Presentations**: title slides, section dividers, bulleted slides with
|
|
160
|
+
indent levels, chart slides, full-width image slides, speaker notes.
|
|
161
|
+
|
|
162
|
+
Filenames from the model are sanitized to their base name, so output can never
|
|
163
|
+
escape the output directory. Image paths must point at existing local files -
|
|
164
|
+
the system prompt tells the model to only use files you mention.
|
|
165
|
+
|
|
166
|
+
## Brand templates
|
|
167
|
+
|
|
168
|
+
Start every generated file from your own template so fonts, colors, and slide
|
|
169
|
+
masters match your brand:
|
|
170
|
+
|
|
171
|
+
```sh
|
|
172
|
+
altr make "..." --docx-template brand.docx --pptx-template brand.pptx
|
|
173
|
+
altr render presentation deck.json --template brand.pptx
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Custom `.pptx` templates must keep the stock layout order (0 title,
|
|
177
|
+
1 title+content, 2 section header, 5 title only).
|
|
178
|
+
|
|
179
|
+
## PDF export
|
|
180
|
+
|
|
181
|
+
Pass `--pdf` to `make` or `render` to also export each created file as PDF.
|
|
182
|
+
Requires LibreOffice (`soffice`) on your PATH. From Python:
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from altr import to_pdf
|
|
186
|
+
to_pdf("output/report.docx")
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
## Roadmap
|
|
190
|
+
|
|
191
|
+
- [ ] Recipe/preset library of reusable prompts
|
|
192
|
+
- [ ] Chart styling options (colors, axis titles, legends)
|
|
193
|
+
- [ ] Nested markdown lists and blockquotes
|
|
194
|
+
- [ ] Watermarks and headers/footers
|
|
195
|
+
|
|
196
|
+
## Contributing
|
|
197
|
+
|
|
198
|
+
PRs welcome - see [CONTRIBUTING.md](CONTRIBUTING.md). Good first issues:
|
|
199
|
+
roadmap items above, or new block types for the document schema.
|
|
200
|
+
|
|
201
|
+
## License
|
|
202
|
+
|
|
203
|
+
[MIT](LICENSE) © Pasindu Suraweera
|
altr_oss-0.2.0/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# altr
|
|
2
|
+
|
|
3
|
+
> Open source doc / excel / ppt skills for LLMs.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/PasinduSuraweera/altr-oss/actions/workflows/ci.yml)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
[](pyproject.toml)
|
|
8
|
+
|
|
9
|
+
Claude has document skills. ChatGPT has them. **Open-weight models don't.**
|
|
10
|
+
Point `gpt-oss-120b` on Groq (or any model behind an OpenAI-compatible API) at
|
|
11
|
+
altr and it gains three tools it can call to produce real files:
|
|
12
|
+
|
|
13
|
+
| Tool | Output | Good for |
|
|
14
|
+
| --------------------- | ------- | ------------------------------------------ |
|
|
15
|
+
| `create_document` | `.docx` | reports, guides, letters, meeting notes |
|
|
16
|
+
| `create_spreadsheet` | `.xlsx` | budgets, trackers, datasets - with formulas |
|
|
17
|
+
| `create_presentation` | `.pptx` | pitch decks, talks - with speaker notes |
|
|
18
|
+
|
|
19
|
+
The model sends structured JSON through standard tool calling; altr
|
|
20
|
+
validates it (Pydantic) and renders it (`python-docx`, `openpyxl`,
|
|
21
|
+
`python-pptx`). Renderer errors are fed back to the model so it can correct
|
|
22
|
+
itself. No code execution, no sandboxes - the model can only emit document
|
|
23
|
+
content.
|
|
24
|
+
|
|
25
|
+
## Install
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pip install altr-oss
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
The PyPI distribution is `altr-oss`; the import and the CLI command are both
|
|
32
|
+
plain `altr`.
|
|
33
|
+
|
|
34
|
+
Or straight from the repo:
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
pip install git+https://github.com/PasinduSuraweera/altr-oss
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quickstart (CLI)
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
export GROQ_API_KEY=gsk_...
|
|
44
|
+
|
|
45
|
+
altr make "Create a 6-slide pitch deck for a solar-powered drone startup"
|
|
46
|
+
altr make "Make a 12-month SaaS budget spreadsheet with formula totals"
|
|
47
|
+
altr make "Write a 2-page onboarding doc for new backend engineers"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Files land in `./output`. Works with any OpenAI-compatible server:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
# Groq (default)
|
|
54
|
+
altr make "..." --model openai/gpt-oss-120b
|
|
55
|
+
|
|
56
|
+
# Ollama, fully local
|
|
57
|
+
altr make "..." --base-url http://localhost:11434/v1 --model llama3.3 --api-key ollama
|
|
58
|
+
|
|
59
|
+
# vLLM / LM Studio / anything else that speaks chat completions
|
|
60
|
+
altr make "..." --base-url http://localhost:8000/v1 --model my-model
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Render a JSON spec directly, no model involved (great for testing):
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
altr render presentation examples/pitch-deck.json
|
|
67
|
+
altr render spreadsheet examples/budget.json
|
|
68
|
+
altr render document examples/onboarding-doc.json
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Use it as a library
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
from altr import OfficeAgent
|
|
75
|
+
|
|
76
|
+
agent = OfficeAgent(model="openai/gpt-oss-120b", out_dir="out")
|
|
77
|
+
result = agent.run("Create a quarterly report with a KPI table")
|
|
78
|
+
print(result.files) # [PosixPath('out/quarterly-report.docx')]
|
|
79
|
+
print(result.reply) # the model's final message
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Use it as a skill in your own agent
|
|
83
|
+
|
|
84
|
+
Already have an agent loop? Take just the tools:
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from altr import SYSTEM_PROMPT, get_tools, dispatch
|
|
88
|
+
|
|
89
|
+
response = client.chat.completions.create(
|
|
90
|
+
model="openai/gpt-oss-120b",
|
|
91
|
+
messages=[{"role": "system", "content": SYSTEM_PROMPT}, ...],
|
|
92
|
+
tools=get_tools(), # OpenAI-format tool definitions
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
for call in response.choices[0].message.tool_calls:
|
|
96
|
+
result = dispatch(call.function.name, call.function.arguments, out_dir="out")
|
|
97
|
+
# {"ok": True, "file": "out/report.docx"} - or {"ok": False, "error": ...}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
`dispatch` never raises on bad model output - validation and render errors come
|
|
101
|
+
back as data you can hand to the model for self-correction.
|
|
102
|
+
|
|
103
|
+
## What the model can express
|
|
104
|
+
|
|
105
|
+
- **Documents**: headings (9 levels), paragraphs with inline
|
|
106
|
+
**bold**/*italic*/`code`, bullet & numbered lists, tables with bold headers,
|
|
107
|
+
images with captions, whole markdown blocks, page breaks.
|
|
108
|
+
- **Spreadsheets**: multiple worksheets, bold header rows, column widths,
|
|
109
|
+
frozen header rows, live Excel formulas (`=SUM(B2:B10)`), and bar/line/pie
|
|
110
|
+
charts built from the sheet's data.
|
|
111
|
+
- **Presentations**: title slides, section dividers, bulleted slides with
|
|
112
|
+
indent levels, chart slides, full-width image slides, speaker notes.
|
|
113
|
+
|
|
114
|
+
Filenames from the model are sanitized to their base name, so output can never
|
|
115
|
+
escape the output directory. Image paths must point at existing local files -
|
|
116
|
+
the system prompt tells the model to only use files you mention.
|
|
117
|
+
|
|
118
|
+
## Brand templates
|
|
119
|
+
|
|
120
|
+
Start every generated file from your own template so fonts, colors, and slide
|
|
121
|
+
masters match your brand:
|
|
122
|
+
|
|
123
|
+
```sh
|
|
124
|
+
altr make "..." --docx-template brand.docx --pptx-template brand.pptx
|
|
125
|
+
altr render presentation deck.json --template brand.pptx
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Custom `.pptx` templates must keep the stock layout order (0 title,
|
|
129
|
+
1 title+content, 2 section header, 5 title only).
|
|
130
|
+
|
|
131
|
+
## PDF export
|
|
132
|
+
|
|
133
|
+
Pass `--pdf` to `make` or `render` to also export each created file as PDF.
|
|
134
|
+
Requires LibreOffice (`soffice`) on your PATH. From Python:
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
from altr import to_pdf
|
|
138
|
+
to_pdf("output/report.docx")
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
## Roadmap
|
|
142
|
+
|
|
143
|
+
- [ ] Recipe/preset library of reusable prompts
|
|
144
|
+
- [ ] Chart styling options (colors, axis titles, legends)
|
|
145
|
+
- [ ] Nested markdown lists and blockquotes
|
|
146
|
+
- [ ] Watermarks and headers/footers
|
|
147
|
+
|
|
148
|
+
## Contributing
|
|
149
|
+
|
|
150
|
+
PRs welcome - see [CONTRIBUTING.md](CONTRIBUTING.md). Good first issues:
|
|
151
|
+
roadmap items above, or new block types for the document schema.
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
[MIT](LICENSE) © Pasindu Suraweera
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"filename": "startup-budget.xlsx",
|
|
3
|
+
"sheets": [
|
|
4
|
+
{
|
|
5
|
+
"name": "Monthly",
|
|
6
|
+
"columns": [
|
|
7
|
+
{ "header": "Item", "width": 28 },
|
|
8
|
+
{ "header": "Cost (USD)", "width": 14 }
|
|
9
|
+
],
|
|
10
|
+
"rows": [
|
|
11
|
+
["Cloud hosting", 320],
|
|
12
|
+
["CI minutes", 45],
|
|
13
|
+
["Domains & certs", 12],
|
|
14
|
+
["Error tracking", 29],
|
|
15
|
+
["Total", "=SUM(B2:B5)"]
|
|
16
|
+
],
|
|
17
|
+
"freeze_header": true,
|
|
18
|
+
"charts": [
|
|
19
|
+
{
|
|
20
|
+
"kind": "bar",
|
|
21
|
+
"title": "Monthly costs",
|
|
22
|
+
"label_column": 1,
|
|
23
|
+
"value_columns": [2]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
]
|
|
28
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"filename": "engineer-onboarding.docx",
|
|
3
|
+
"title": "Engineering Onboarding Guide",
|
|
4
|
+
"blocks": [
|
|
5
|
+
{ "type": "heading", "level": 1, "text": "Week one" },
|
|
6
|
+
{ "type": "paragraph", "text": "Welcome aboard! This guide walks you through your first week." },
|
|
7
|
+
{
|
|
8
|
+
"type": "bullet_list",
|
|
9
|
+
"items": [
|
|
10
|
+
"Get repo access and clone the monorepo",
|
|
11
|
+
"Run the dev environment bootstrap script",
|
|
12
|
+
"Ship one small PR by Friday"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{ "type": "heading", "level": 1, "text": "Key contacts" },
|
|
16
|
+
{
|
|
17
|
+
"type": "table",
|
|
18
|
+
"headers": ["Area", "Owner"],
|
|
19
|
+
"rows": [
|
|
20
|
+
["Infrastructure", "Priya"],
|
|
21
|
+
["Frontend", "Marco"],
|
|
22
|
+
["On-call schedule", "PagerDuty rota"]
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"filename": "solar-drones-pitch.pptx",
|
|
3
|
+
"slides": [
|
|
4
|
+
{
|
|
5
|
+
"layout": "title",
|
|
6
|
+
"title": "SolarDrones",
|
|
7
|
+
"subtitle": "Autonomous solar-powered delivery - Series A"
|
|
8
|
+
},
|
|
9
|
+
{
|
|
10
|
+
"layout": "bullets",
|
|
11
|
+
"title": "The problem",
|
|
12
|
+
"bullets": [
|
|
13
|
+
{ "text": "Last-mile delivery is 53% of shipping cost" },
|
|
14
|
+
{ "text": "Diesel fleets face tightening emissions rules" },
|
|
15
|
+
{ "text": "Rural coverage is unprofitable today", "level": 1 }
|
|
16
|
+
],
|
|
17
|
+
"notes": "Open with the cost number - it lands well."
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
"layout": "section",
|
|
21
|
+
"title": "Our solution"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"layout": "bullets",
|
|
25
|
+
"title": "Solar-recharging drone network",
|
|
26
|
+
"bullets": [
|
|
27
|
+
{ "text": "18 kg payload, 120 km range" },
|
|
28
|
+
{ "text": "Zero-cost recharge at solar relay stations" },
|
|
29
|
+
{ "text": "FAA Part 135 certification in progress" }
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
]
|
|
33
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "altr-oss"
|
|
7
|
+
version = "0.2.0"
|
|
8
|
+
description = "Open source doc / excel / ppt skills for LLMs - Groq, Ollama, vLLM, any OpenAI-compatible endpoint."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = { file = "LICENSE" }
|
|
11
|
+
authors = [{ name = "Pasindu Suraweera" }]
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
keywords = ["llm", "tool-calling", "skills", "groq", "gpt-oss", "docx", "xlsx", "pptx"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Topic :: Office/Business :: Office Suites",
|
|
23
|
+
"Topic :: Scientific/Engineering :: Artificial Intelligence",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"openai>=1.40",
|
|
27
|
+
"pydantic>=2.7",
|
|
28
|
+
"python-docx>=1.1",
|
|
29
|
+
"openpyxl>=3.1",
|
|
30
|
+
"python-pptx>=1.0",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.optional-dependencies]
|
|
34
|
+
dev = ["pytest>=8"]
|
|
35
|
+
|
|
36
|
+
[project.scripts]
|
|
37
|
+
altr = "altr.cli:main"
|
|
38
|
+
|
|
39
|
+
[project.urls]
|
|
40
|
+
Homepage = "https://github.com/PasinduSuraweera/altr-oss"
|
|
41
|
+
|
|
42
|
+
[tool.hatch.build.targets.wheel]
|
|
43
|
+
packages = ["src/altr"]
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""altr - open source doc/excel/ppt skills for LLMs."""
|
|
2
|
+
|
|
3
|
+
from .agent import DEFAULT_MODEL, GROQ_BASE_URL, OfficeAgent, RunResult
|
|
4
|
+
from .markdown import markdown_to_blocks
|
|
5
|
+
from .pdf import soffice_available, to_pdf
|
|
6
|
+
from .prompts import SYSTEM_PROMPT
|
|
7
|
+
from .schemas import DocumentSpec, PresentationSpec, SpreadsheetSpec
|
|
8
|
+
from .tools import dispatch, get_tools
|
|
9
|
+
|
|
10
|
+
__all__ = [
|
|
11
|
+
"OfficeAgent",
|
|
12
|
+
"RunResult",
|
|
13
|
+
"SYSTEM_PROMPT",
|
|
14
|
+
"DEFAULT_MODEL",
|
|
15
|
+
"GROQ_BASE_URL",
|
|
16
|
+
"DocumentSpec",
|
|
17
|
+
"SpreadsheetSpec",
|
|
18
|
+
"PresentationSpec",
|
|
19
|
+
"get_tools",
|
|
20
|
+
"dispatch",
|
|
21
|
+
"markdown_to_blocks",
|
|
22
|
+
"to_pdf",
|
|
23
|
+
"soffice_available",
|
|
24
|
+
]
|