@qvac/skills 0.1.11 → 0.1.13
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.
- package/bundled.js +8 -24
- package/hash.js +1 -1
- package/package.json +1 -1
- package/skills/browser/SKILL.md +78 -0
- package/skills/browser/cli.schema.json +276 -0
- package/skills/excel/SKILL.md +146 -111
- package/skills/music-generation/SKILL.md +15 -0
- package/skills/pdf/SKILL.md +146 -96
- package/skills/presentations/SKILL.md +133 -109
- package/skills/sheet-music/SKILL.md +93 -0
- package/skills/word/SKILL.md +144 -124
- package/skills/excel/references/create.md +0 -374
- package/skills/excel/references/edit.md +0 -357
- package/skills/excel/references/read.md +0 -99
- package/skills/pdf/references/create.md +0 -169
- package/skills/pdf/references/transform.md +0 -270
- package/skills/pdf/scripts/decrypt.py +0 -26
- package/skills/pdf/scripts/encrypt.py +0 -25
- package/skills/pdf/scripts/extract_text.py +0 -25
- package/skills/pdf/scripts/merge.py +0 -21
- package/skills/pdf/scripts/rotate.py +0 -27
- package/skills/presentations/references/create.md +0 -399
- package/skills/presentations/references/edit.md +0 -314
- package/skills/presentations/references/read.md +0 -127
- package/skills/word/references/create.md +0 -400
- package/skills/word/references/paragraphs.md +0 -125
- package/skills/word/references/read.md +0 -141
- package/skills/word/references/rework.md +0 -767
- package/skills/word/scripts/list_paragraphs.py +0 -25
- package/skills/word/scripts/replace_paragraphs.py +0 -58
package/skills/pdf/SKILL.md
CHANGED
|
@@ -1,110 +1,160 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pdf
|
|
3
|
-
description:
|
|
4
|
-
tools: [
|
|
5
|
-
platform: [darwin, linux, win32]
|
|
6
|
-
metadata:
|
|
7
|
-
{
|
|
8
|
-
"openclaw":
|
|
9
|
-
{
|
|
10
|
-
"setup":
|
|
11
|
-
{
|
|
12
|
-
"summary": "Runs pypdf and fpdf2 in the in-process Python runtime, from packages that ship with the app. The first use waits for the runtime to start."
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
3
|
+
description: Read, answer questions about, create, merge, split, rotate, watermark, password-protect, unlock, fill in, or pull the text out of PDF files, including any attached .pdf — always this skill, never Python, for a PDF — and deliver the result as a chat attachment.
|
|
4
|
+
tools: [pdf]
|
|
5
|
+
platform: [darwin, linux, win32, ios, android]
|
|
16
6
|
---
|
|
17
7
|
|
|
18
8
|
# PDF
|
|
19
9
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
10
|
+
Every PDF job is one or two `pdf` tool calls. A call with an `action` saves a
|
|
11
|
+
new file named `output` and attaches it to the chat; a call without `action`
|
|
12
|
+
changes nothing and returns what the PDF holds.
|
|
13
|
+
|
|
14
|
+
## Pick the Call
|
|
15
|
+
|
|
16
|
+
| The user wants | The `pdf` call |
|
|
17
|
+
| ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
18
|
+
| A new PDF — "write a report", "make a cheat sheet" | `{ "action": "create", "markdown": "# Cat Facts\n\n...", "output": "cat_facts.pdf" }` |
|
|
19
|
+
| New or changed words in an existing PDF | read first, then one `create` call with the whole document |
|
|
20
|
+
| "Merge these PDFs", "combine them into one" | `{ "action": "merge", "attachmentIds": ["4f9c2ab1", "9be07c12"], "output": "merged.pdf" }` |
|
|
21
|
+
| "Keep pages 1-3", "split out page 5" | `{ "action": "split", "attachmentId": "4f9c2ab1", "pages": [1, 2, 3], "output": "report_pages_1-3.pdf" }` |
|
|
22
|
+
| "Delete page 3", "remove the last page" | `split` with every page to keep: a 4-page PDF without page 3 is `{ "action": "split", "attachmentId": "4f9c2ab1", "pages": [1, 2, 4], "output": "report_without_page_3.pdf" }` |
|
|
23
|
+
| "Rotate it", "turn page 2 sideways" | `{ "action": "rotate", "attachmentId": "4f9c2ab1", "degrees": 90, "pages": [2], "output": "report_rotated.pdf" }` |
|
|
24
|
+
| "Stamp DRAFT on every page", "add a watermark" | `{ "action": "watermark", "attachmentId": "4f9c2ab1", "text": "DRAFT", "output": "report_draft.pdf" }` |
|
|
25
|
+
| "Fill in this form" | read first, then `{ "action": "fill", "attachmentId": "4f9c2ab1", "values": { "name": "Ada Lovelace", "agree": true }, "output": "form_filled.pdf" }` |
|
|
26
|
+
| "Put a password on it", "lock it" | `{ "action": "encrypt", "attachmentId": "4f9c2ab1", "password": "s3cret", "output": "report_locked.pdf" }` |
|
|
27
|
+
| "Remove the password", "unlock it" | `{ "action": "decrypt", "attachmentId": "4f9c2ab1", "password": "s3cret", "output": "report_unlocked.pdf" }` |
|
|
28
|
+
| "Give me the text as a file" | `{ "action": "text", "attachmentId": "4f9c2ab1", "output": "report.txt" }` |
|
|
29
|
+
| What is in it — its pages, text, or form fields | `{ "attachmentId": "4f9c2ab1" }` |
|
|
30
|
+
|
|
31
|
+
- `pages` counts the way the user does: `1` is the first page. Leave `pages`
|
|
32
|
+
out and `rotate` and `watermark` apply to every page.
|
|
33
|
+
- `merge` joins the files in the order of `attachmentIds`.
|
|
34
|
+
- `degrees` is `90`, `180` or `270`, clockwise.
|
|
35
|
+
- `watermark` also takes `"opacity": 0.2` (0 to 1) and `"position": "under"`
|
|
36
|
+
to put the mark behind the content.
|
|
37
|
+
- `encrypt` locks the file with AES-256. Add `"ownerPassword": "admin"` and
|
|
38
|
+
`"permissions": { "print": false, "copy": false }` to restrict what a viewer
|
|
39
|
+
allows.
|
|
40
|
+
- A locked PDF needs its password on every action, not only `decrypt`:
|
|
41
|
+
`{ "action": "rotate", "attachmentId": "4f9c2ab1", "password": "s3cret", "degrees": 90, "output": "report_rotated.pdf" }`.
|
|
42
|
+
The password always comes from the user — never guess one.
|
|
43
|
+
|
|
44
|
+
## A New PDF
|
|
45
|
+
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"action": "create",
|
|
49
|
+
"markdown": "# Cat Facts\n\n## Senses\n\n- A cat's hearing reaches **64 kHz**.\n- Cats have about 200 million scent receptors.\n\n## Sleep\n\nCats sleep 12 to 16 hours a day, most of it in short naps.\n\n| Breed | Weight (kg) |\n| --- | --- |\n| Siamese | 4 |\n| Maine Coon | 8 |\n",
|
|
50
|
+
"output": "cat_facts.pdf"
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
- `markdown` is the whole document: `#` headings, paragraphs, `-` and `1.`
|
|
55
|
+
lists, `**bold**`, `*italic*`, `>` quotes, fenced code, tables, `---` rules
|
|
56
|
+
and `\pagebreak`. The tool lays it out, wraps it and adds pages itself.
|
|
57
|
+
- **Write the whole document, not a cover page.** "A small PDF about X" still
|
|
58
|
+
means a title, then several short sections, each a heading plus a paragraph
|
|
59
|
+
or bullets. The content belongs inside the PDF, not in your chat reply.
|
|
60
|
+
- `create` also takes `"pageSize": "Letter"` (the default is `A4`; `A5` and
|
|
61
|
+
`Legal` work too), `"landscape": true` and `"pageNumbers": true`.
|
|
62
|
+
- Lock a new PDF only when the user asks for a password, and use the one the
|
|
63
|
+
user gave: add `"password"` with it. Otherwise leave `password` out.
|
|
64
|
+
- Western European text only: accents, curly quotes, dashes and `€` are fine.
|
|
65
|
+
A character outside it (Chinese, Cyrillic, emoji) fails the call and the
|
|
66
|
+
error names it — leave it out, or tell the user it cannot be drawn.
|
|
67
|
+
- A picture goes on its own line as ``:
|
|
68
|
+
`` for an image this chat generated, or
|
|
69
|
+
`` — the file name — for an image the user uploaded.
|
|
70
|
+
Only PNG and JPEG images work, and an image behind a URL cannot be
|
|
71
|
+
downloaded.
|
|
72
|
+
|
|
73
|
+
## Changing the Words in an Existing PDF
|
|
74
|
+
|
|
75
|
+
A PDF's pages cannot be edited in place. Adding a paragraph, rewording, or
|
|
76
|
+
restyling is a REBUILD: read the PDF when its text is not already in this chat,
|
|
77
|
+
then one `create` call with every original section, unchanged, plus the
|
|
78
|
+
requested change. A rebuild that condenses, summarizes, or drops original
|
|
79
|
+
sections is a failed turn. Name it after the original: `report.pdf` →
|
|
80
|
+
`report_revised.pdf`.
|
|
81
|
+
|
|
82
|
+
**Keep the original pages.** Write each page's text from the read and put
|
|
83
|
+
`\pagebreak` between the pages, so the rebuild has the original page count. A
|
|
84
|
+
page the user asks to add goes where they asked, after its own `\pagebreak`.
|
|
85
|
+
A 3-page report with a line fixed on page 2:
|
|
86
|
+
|
|
87
|
+
```json
|
|
88
|
+
{
|
|
89
|
+
"action": "create",
|
|
90
|
+
"markdown": "# Annual Report\n\nPage 1 text, unchanged.\n\n\\pagebreak\n\n## Costs\n\nPage 2 text, with the fixed line.\n\n\\pagebreak\n\n## Outlook\n\nPage 3 text, unchanged.\n",
|
|
91
|
+
"output": "report_revised.pdf"
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
A picture cannot be added to an existing PDF's pages. Tell the user, or offer
|
|
96
|
+
a rebuild with the picture at the top, which keeps the words but not the
|
|
97
|
+
original layout.
|
|
98
|
+
|
|
99
|
+
## Attachment Ids
|
|
100
|
+
|
|
101
|
+
The id comes from the tool result that produced the PDF, or from the user's
|
|
102
|
+
`[Attached file …]` line:
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
[Attached file "contract.pdf" (application/pdf) — attachmentId: 4f9c2ab1]
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Copy the id verbatim. Never make one up. If no id for the PDF is in the chat,
|
|
109
|
+
ask the user to attach it again.
|
|
110
|
+
|
|
111
|
+
## Reading a PDF
|
|
112
|
+
|
|
113
|
+
```json
|
|
114
|
+
{ "attachmentId": "4f9c2ab1" }
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
It returns the page count, each page's text, and the form fields — each with
|
|
118
|
+
its `name`, `type`, current `value`, and the `options` a choice field accepts.
|
|
119
|
+
You cannot fill a form or write a summary in the same call that reads, because
|
|
120
|
+
the values are fixed before the PDF is opened. Read, then act on what came
|
|
121
|
+
back.
|
|
122
|
+
|
|
123
|
+
- **Filling a form** — `values` keys are the exact field `name`s from the
|
|
124
|
+
read. A checkbox takes `true` or `false`; a radio group or dropdown takes one
|
|
125
|
+
of its `options`. A PDF with no fields has no form layer: say so instead of
|
|
126
|
+
guessing where the text goes.
|
|
127
|
+
- **A page with empty text is a scanned image.** There is no OCR here — tell
|
|
128
|
+
the user those pages are images rather than calling again.
|
|
129
|
+
- **A question about an attached PDF** ("summarize this", "what does it say
|
|
130
|
+
about X") — answer from the document text already in the chat. Read only
|
|
131
|
+
when that text is missing.
|
|
65
132
|
|
|
66
133
|
## When NOT to Use
|
|
67
134
|
|
|
68
|
-
- A `create_pdf` tool is available in this chat and the user only wants prose
|
|
69
|
-
you are writing turned into a downloadable document — call `create_pdf` with
|
|
70
|
-
the markdown instead; it is cheaper and handles layout itself. Reach for this
|
|
71
|
-
skill when that tool is absent on this device, when an existing PDF is
|
|
72
|
-
involved, or when the layout must be controlled page by page.
|
|
73
|
-
- The user asks about an attached PDF — answer from the document text or
|
|
74
|
-
knowledge excerpts already in the chat. Run text extraction only when the
|
|
75
|
-
user wants the text itself delivered as a file.
|
|
76
135
|
- The user wants a slide deck — use the presentations skill; a spreadsheet or
|
|
77
|
-
Word file —
|
|
136
|
+
Word file — the excel or word skill.
|
|
78
137
|
- The user wants a single image — call `generate_image` alone.
|
|
79
138
|
|
|
80
139
|
## Rules for Every Job
|
|
81
140
|
|
|
82
|
-
**You build it, not the user.**
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
**The runtime is sealed.** There is no shell (`ls`, `cat` raise
|
|
104
|
-
`SyntaxError` — the `command` is Python source) and no network — `requests`,
|
|
105
|
-
`urllib`, and `socket` all fail, so a PDF behind a URL cannot be downloaded;
|
|
106
|
-
ask the user to attach the file. The working directory starts empty on every
|
|
107
|
-
call: a file from an earlier call is gone unless staged again, and a file you
|
|
108
|
-
write but do not declare in `outputs` is discarded.
|
|
109
|
-
|
|
110
|
-
**Never overwrite a staged input.** Transforms always write a new output name.
|
|
141
|
+
**You build it, not the user.** The PDF exists only when a call returns its
|
|
142
|
+
attachment. Never write it as chat text instead, and never tell the user to
|
|
143
|
+
run anything.
|
|
144
|
+
|
|
145
|
+
**Success = stop.** When the result lists the attachment, your whole answer is
|
|
146
|
+
the result's `reply` line — the file name and the page count — and you call
|
|
147
|
+
nothing else.
|
|
148
|
+
|
|
149
|
+
**Never overwrite the input.** Name the output after the file you opened:
|
|
150
|
+
`report.pdf` → `report_rotated.pdf`. Never the input's own name.
|
|
151
|
+
|
|
152
|
+
**Errors name the fix.** A failed call says what is wrong — a page out of
|
|
153
|
+
range and how many pages there are, a field name and the fields that exist, a
|
|
154
|
+
value and the options it takes, a wrong or missing password, a character the
|
|
155
|
+
font cannot draw. Correct that one argument and call again. Never repeat an
|
|
156
|
+
identical call, and never switch to exec, Python or the shell for a PDF job:
|
|
157
|
+
the `pdf` tool is the only way this skill works.
|
|
158
|
+
|
|
159
|
+
**No network.** A PDF behind a URL cannot be downloaded — ask the user to
|
|
160
|
+
attach the file.
|
|
@@ -1,118 +1,142 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: presentations
|
|
3
|
-
description: Create, edit, or read PowerPoint (.pptx) decks
|
|
4
|
-
tools: [
|
|
5
|
-
platform: [darwin, linux, win32]
|
|
6
|
-
metadata:
|
|
7
|
-
{
|
|
8
|
-
"openclaw":
|
|
9
|
-
{
|
|
10
|
-
"setup":
|
|
11
|
-
{
|
|
12
|
-
"summary": "Runs python-pptx in the in-process Python runtime, from packages that ship with the app. The first use waits for the runtime to start."
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
}
|
|
3
|
+
description: Create, edit, or read PowerPoint (.pptx) decks — deliver decks as chat attachments, or read an attached one to summarize it or answer questions in the chat. Can embed images the user attached to the chat as well as images generated in it.
|
|
4
|
+
tools: [pptx]
|
|
5
|
+
platform: [darwin, linux, win32, ios, android]
|
|
16
6
|
---
|
|
17
7
|
|
|
18
8
|
# Presentations
|
|
19
9
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
10
|
+
Every deck job is one or two `pptx` tool calls. A call with `ops` saves a new
|
|
11
|
+
file named `output` and attaches it to the chat; a call without `ops` changes
|
|
12
|
+
nothing and returns what the deck holds.
|
|
13
|
+
|
|
14
|
+
## Pick the Call
|
|
15
|
+
|
|
16
|
+
| The user wants | The calls |
|
|
17
|
+
| ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
|
|
18
|
+
| A new deck — "make slides about …", "a deck with this image" | one call: `create` + `ops` + `output` |
|
|
19
|
+
| A mechanical edit — "make the title red", "retitle slide 1 to …" | one call: `attachmentId` + `ops` + `output` |
|
|
20
|
+
| An edit whose words depend on the deck — "add a summary slide", "fix typos" | read (`attachmentId` alone), then one edit call |
|
|
21
|
+
| An answer in the chat — "summarize this deck", "what does slide 3 say?" | read (`attachmentId` alone), then reply in the chat — no second call |
|
|
22
|
+
| A summary of the deck as a new file | read, then one `create` call written from what the read returned |
|
|
23
|
+
|
|
24
|
+
A deck already in this chat is never rebuilt with `create` — that throws away
|
|
25
|
+
every slide the user has. Its `attachmentId` is in the tool result that
|
|
26
|
+
produced it, or on the user's `[Attached file …]` line:
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
[Attached file "quarterly.pptx" (application/vnd.openxmlformats-officedocument.presentationml.presentation) — attachmentId: 4f9c2ab1]
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Copy the id verbatim. Never make one up.
|
|
33
|
+
|
|
34
|
+
## A New Deck
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{
|
|
38
|
+
"create": { "size": "16:9" },
|
|
39
|
+
"ops": [
|
|
40
|
+
{ "op": "addSlide", "layout": "Title Slide", "title": "Why the Sky Is Blue", "body": "Rayleigh scattering, in four points" },
|
|
41
|
+
{ "op": "addSlide", "title": "What Happens", "body": [
|
|
42
|
+
"Sunlight carries every visible wavelength",
|
|
43
|
+
"Air scatters short wavelengths hardest",
|
|
44
|
+
{ "text": "Blue scatters far more than red", "level": 1 },
|
|
45
|
+
"So the sky reads blue in every direction"
|
|
46
|
+
] },
|
|
47
|
+
{ "op": "addSlide", "layout": "Title Only", "title": "By Wavelength" },
|
|
48
|
+
{ "op": "addChart", "slide": 2, "type": "column", "title": "Scattered light",
|
|
49
|
+
"categories": ["Blue", "Green", "Red"], "series": [{ "name": "Relative", "values": [5.5, 3.1, 1] }] }
|
|
50
|
+
],
|
|
51
|
+
"output": "sky.pptx"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Layouts in a new deck: `Title Slide`, `Title and Content` (the default),
|
|
56
|
+
`Section Header`, `Two Content`, `Title Only`, `Blank`. Each bullet is its own
|
|
57
|
+
item in `body` — never type `-`, `•` or `1.` in front of it; the slide draws
|
|
58
|
+
the bullet. Five bullets per slide at most; a sixth is a new slide titled
|
|
59
|
+
`… (cont.)`.
|
|
60
|
+
|
|
61
|
+
## Reading a Deck
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{ "attachmentId": "4f9c2ab1" }
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
It returns every slide with its index, layout and shapes — each shape's `id`,
|
|
68
|
+
`name`, and its paragraphs or table rows — plus speaker notes. You cannot write
|
|
69
|
+
a summary or a closing slide in the same call that reads, because the words
|
|
70
|
+
are fixed before the deck is opened. Read, then write from what came back.
|
|
71
|
+
|
|
72
|
+
## Editing a Deck
|
|
73
|
+
|
|
74
|
+
```json
|
|
75
|
+
{
|
|
76
|
+
"attachmentId": "4f9c2ab1",
|
|
77
|
+
"ops": [
|
|
78
|
+
{ "op": "setText", "slide": 0, "shape": "title", "text": "Why the Sky Is Blue — Revised" },
|
|
79
|
+
{ "op": "setStyle", "slide": 0, "shape": "title", "style": { "color": "C0392B", "bold": true } },
|
|
80
|
+
{ "op": "addSlide", "title": "What Changed", "body": ["Retitled the cover", "Recoloured the title"] }
|
|
81
|
+
],
|
|
82
|
+
"output": "quarterly-v2.pptx"
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Slides count from 0. A `shape` is `"title"`, `"subtitle"`, `"body"`, or the
|
|
87
|
+
`id` a read returned.
|
|
88
|
+
|
|
89
|
+
| The change | The op |
|
|
90
|
+
| ---------------------------- | ------------------------------------------------------------------------------------------ |
|
|
91
|
+
| Replace a shape's text | `{ "op": "setText", "slide": 1, "shape": "body", "text": ["First", "Second"] }` |
|
|
92
|
+
| Replace one table cell | `{ "op": "setCellText", "slide": 2, "shape": 4, "row": 1, "column": 1, "text": "450 nm" }` |
|
|
93
|
+
| Size, colour, font, bold | `{ "op": "setStyle", "slide": 0, "shape": "title", "style": { "size": 40, "font": "Georgia" } }` |
|
|
94
|
+
| Add a slide like its neighbours | `{ "op": "addSlide", "title": "Next Steps", "body": ["Ship it"] }` |
|
|
95
|
+
| Add a slide at a position | `{ "op": "addSlide", "at": 1, "title": "Agenda", "body": ["Why", "How"] }` |
|
|
96
|
+
| Delete a slide | `{ "op": "deleteSlide", "slide": 3 }` |
|
|
97
|
+
| Move a slide | `{ "op": "moveSlide", "from": 4, "to": 1 }` |
|
|
98
|
+
| Add a picture | `{ "op": "addPicture", "slide": 2, "image": { "attachmentId": "9be07c12" }, "width": 6 }` |
|
|
99
|
+
| Add a free text box | `{ "op": "addTextBox", "slide": 5, "text": "Thanks", "style": { "size": 54, "align": "center" } }` |
|
|
100
|
+
| Add a table | `{ "op": "addTable", "slide": 3, "rows": [["Band", "nm"], ["Blue", 450]], "header": true }` |
|
|
101
|
+
| Change a chart's numbers | `{ "op": "setChartData", "slide": 2, "shape": 4, "categories": ["Q1", "Q2"], "series": [{ "name": "2026", "values": [11, 13] }] }` |
|
|
102
|
+
| Retitle a chart | `{ "op": "setChartTitle", "slide": 2, "shape": 4, "title": "Revenue by quarter" }` |
|
|
103
|
+
| Solid background | `{ "op": "setBackground", "slide": 5, "color": "101820" }` |
|
|
104
|
+
|
|
105
|
+
`addSlide` without `layout` copies the layout of the deck's last content slide,
|
|
106
|
+
so the new slide matches its neighbours. Never pick `Blank` for an ordinary
|
|
107
|
+
title-and-bullets slide on a deck the user gave you. Positions and sizes (`x`,
|
|
108
|
+
`y`, `width`, `height`) are inches; give one of `width`/`height` and the
|
|
109
|
+
picture keeps its shape. Colours are six hex digits, no `#`.
|
|
110
|
+
|
|
111
|
+
Name the output after the deck you opened and bump a version: `quarterly.pptx`
|
|
112
|
+
→ `quarterly-v2.pptx`, and an edit of that → `quarterly-v3.pptx`. Never the
|
|
113
|
+
input's own name.
|
|
114
|
+
|
|
115
|
+
## Images
|
|
116
|
+
|
|
117
|
+
- An image this chat generated: `"image": { "attachmentId": "<id from the generate_image result>" }`.
|
|
118
|
+
- An image the user attached to their latest message: `"image": {}` — an
|
|
119
|
+
uploaded image shows no id, and the empty form picks it up.
|
|
120
|
+
- An image behind a URL cannot be downloaded. Say so, and ask the user to attach
|
|
121
|
+
it or offer `generate_image`.
|
|
71
122
|
|
|
72
123
|
## Rules for Every Job
|
|
73
124
|
|
|
74
|
-
**You build it, not the user.**
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
**Failures are fixed in the code, not around it.** If a run fails, fix the
|
|
94
|
-
Python against the loaded reference file's recipes and errors table and call
|
|
95
|
-
`exec` again. If two consecutive calls fail with the same error, the fix from
|
|
96
|
-
the first attempt did not land — re-read the traceback line-by-line before a
|
|
97
|
-
third call; retrying the identical `command`, or a version with only cosmetic
|
|
98
|
-
changes, is a loop, not a fix. An error in your code is never a fault in
|
|
99
|
-
python-pptx or in the runtime: do not switch package pins or hunt a "more
|
|
100
|
-
compatible" version — keep `packages: ["python-pptx==1.0.2"]` — do not wrap
|
|
101
|
-
source in `python -c "…"`, `python3`, `pip`, or shell, and do not "debug" with
|
|
102
|
-
`os.listdir`, `print`, or a non-deck script while `outputs` still lists the
|
|
103
|
-
deck. Never search the web about an error; the answer is always in the result
|
|
104
|
-
you already have.
|
|
105
|
-
|
|
106
|
-
**The runtime is sealed.** There is no shell — `ls`, `cat` and `file` raise
|
|
107
|
-
`SyntaxError`, because the `command` is Python source — and no filesystem to
|
|
108
|
-
check outside the `exec` result. There is no network: `requests`, `urllib`,
|
|
109
|
-
and `socket` all fail, and `http_request` returns truncated text, never image
|
|
110
|
-
bytes — an image behind a URL cannot be downloaded; ask the user to attach it
|
|
111
|
-
or offer `generate_image`. The working directory starts empty on every call:
|
|
112
|
-
a file from an earlier call is gone unless staged again by its attachment id,
|
|
113
|
-
and a file you write but do not declare in `outputs` is discarded.
|
|
114
|
-
|
|
115
|
-
**Never overwrite a staged input.** An edit always saves under a new,
|
|
116
|
-
version-bumped name — `deck.pptx` → `deck-v2.pptx` — and a corrected rebuild
|
|
117
|
-
after a broken delivery goes out under the next version, never the name
|
|
118
|
-
already attached this turn.
|
|
125
|
+
**You build it, not the user.** The deck exists only when a `pptx` call with
|
|
126
|
+
`ops` returns its attachment. Never write the slides as chat text instead, and
|
|
127
|
+
never tell the user to run anything.
|
|
128
|
+
|
|
129
|
+
**Success = stop.** When the result lists the attachment, reply with one line —
|
|
130
|
+
the file name and the slide count — and call nothing else. Check `slides` in
|
|
131
|
+
the result against the request first: one slide added to a 2-slide deck is
|
|
132
|
+
`3`; `4` means an op ran twice, so fix the ops and send them again under the
|
|
133
|
+
next version name.
|
|
134
|
+
|
|
135
|
+
**Errors name the fix.** A failed call returns a message that says what exists
|
|
136
|
+
— `slide 7 does not exist; the deck has 3 slides (0 to 2)`, or the shapes on
|
|
137
|
+
the slide. Correct that one op and call again. Never repeat an identical call.
|
|
138
|
+
|
|
139
|
+
## What This Cannot Do
|
|
140
|
+
|
|
141
|
+
Say so instead of faking it: writing speaker notes, editing scatter, bubble or
|
|
142
|
+
stock charts, SmartArt, and legacy `.ppt` files.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sheet-music
|
|
3
|
+
description: Turn audio into sheet music. Transcribe a recording or a generated track into a score you can read, print, or open in any notation app.
|
|
4
|
+
tools: [transcribe_music]
|
|
5
|
+
platform: [darwin, linux, win32]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Sheet music
|
|
9
|
+
|
|
10
|
+
Call `transcribe_music` when the user wants notation for audio that already
|
|
11
|
+
exists: sheet music, a score, the chords, the notes, the melody, "write this
|
|
12
|
+
out". It reads an audio attachment from the chat and saves a `.musicxml` score,
|
|
13
|
+
which the app shows as readable sheet music in the conversation with a PDF
|
|
14
|
+
download; it also opens in MuseScore, Sibelius or Dorico.
|
|
15
|
+
|
|
16
|
+
```json
|
|
17
|
+
{ "title": "kitchen demo" }
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Do not invent an `attachmentId`.** An attached audio file never appears in the
|
|
21
|
+
conversation with an id, so there is nothing to copy: leaving the field out is
|
|
22
|
+
how you say "the track the user just attached".
|
|
23
|
+
|
|
24
|
+
## When to Use
|
|
25
|
+
|
|
26
|
+
- The user attached audio and wants it written out as notation.
|
|
27
|
+
- A track was generated earlier in this chat and the user now asks for its sheet
|
|
28
|
+
music, chords, or notes.
|
|
29
|
+
- The user asks what notes or chords are in a recording.
|
|
30
|
+
|
|
31
|
+
## When NOT to Use
|
|
32
|
+
|
|
33
|
+
- The user is asking for a *new* song — that is `generate_music`. If they want the
|
|
34
|
+
track and its sheet music together, call `generate_music` with
|
|
35
|
+
`sheetMusic: true` instead of making two calls.
|
|
36
|
+
- The user wants spoken words written down — that is speech transcription, not
|
|
37
|
+
this.
|
|
38
|
+
|
|
39
|
+
**If `transcribe_music` returns an error, report it and stop.** Never fall back to
|
|
40
|
+
`generate_music`: that writes a brand new piece, and presenting it as the user's
|
|
41
|
+
transcription is a lie about their own audio. The error text says what to change,
|
|
42
|
+
usually to omit `attachmentId`, so read it and retry the same tool.
|
|
43
|
+
|
|
44
|
+
## Parameters
|
|
45
|
+
|
|
46
|
+
- `attachmentId` — **omit it** to transcribe the most recent audio in the chat,
|
|
47
|
+
which is what an attached track means. Pass one only to reach back to an older
|
|
48
|
+
track whose id a previous `generate_music` actually returned.
|
|
49
|
+
- `title` — a short title, 2 to 5 words; it names the saved files.
|
|
50
|
+
- `bpm` — pass it whenever the tempo is known. **If you generated the track in
|
|
51
|
+
this chat with a `bpm`, pass that same value here.** Tempo estimated from audio
|
|
52
|
+
is right about the beat but can land an octave off (60 where the track is 120),
|
|
53
|
+
and a known tempo removes that guess entirely.
|
|
54
|
+
- `keyscale` — same idea for the key, e.g. `C minor`. Estimated when omitted.
|
|
55
|
+
|
|
56
|
+
## What comes back
|
|
57
|
+
|
|
58
|
+
The result names the score attachment and reports what was transcribed: `notes`,
|
|
59
|
+
`bars`, `bpm`, `key`, how many artifacts were filtered out, and two flags worth
|
|
60
|
+
reading before you reply:
|
|
61
|
+
|
|
62
|
+
- `tempoFromRequest` — false means the tempo was estimated. Worth a word to the
|
|
63
|
+
user if the rhythm looks doubled or halved.
|
|
64
|
+
- `melodyMissing` — nothing was found above middle C. Say so plainly: on a dense
|
|
65
|
+
mix the transcription captures the bass and the loudest lines, and the melody
|
|
66
|
+
is buried. Do not present that score as a full transcription.
|
|
67
|
+
|
|
68
|
+
## Honesty about quality
|
|
69
|
+
|
|
70
|
+
This is automatic transcription, not a human copyist, and the result depends
|
|
71
|
+
almost entirely on how dense the audio is.
|
|
72
|
+
|
|
73
|
+
- **A solo instrument or a small ensemble transcribes well.** Piano, guitar,
|
|
74
|
+
a single voice, a duo.
|
|
75
|
+
- **A full band mix does not.** Distortion and cymbals mask everything in the
|
|
76
|
+
middle, so what survives is the bass line and whichever line is loudest.
|
|
77
|
+
- Percussion is not pitched and is not transcribed.
|
|
78
|
+
- Sustained notes are approximate: the score reads the right pitches with
|
|
79
|
+
quantized rhythm, not a performance-accurate transcription.
|
|
80
|
+
|
|
81
|
+
Tell the user which of these they are getting rather than letting them discover
|
|
82
|
+
it.
|
|
83
|
+
|
|
84
|
+
## A track and its score together
|
|
85
|
+
|
|
86
|
+
Sheet music never changes the track. Generate what the user asked for: their
|
|
87
|
+
duration, their instrumentation, their genre.
|
|
88
|
+
|
|
89
|
+
Dense or long material makes a crowded score, and that is worth saying. Before
|
|
90
|
+
generating, when they have left the choice open, offer it: a sparse 30-60 second
|
|
91
|
+
piece gives a score a person can actually read. After generating, say plainly
|
|
92
|
+
what they got when the result comes back with `melodyMissing` or sixty-odd bars.
|
|
93
|
+
Never quietly substitute something shorter or sparser than they asked for.
|