CtrlK
BlogDocsLog inGet started
Tessl Logo

pdf

Create polished PDF files for requests such as PDFs, resumes, CVs, reports, letters, one-pagers, and printable documents.

64

Quality

76%

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

Passed

No findings from the security scan

Fix and improve this skill with Tessl

tessl review fix ./docker/sandbox/skills/pdf/SKILL.md
SKILL.md
Quality
Evals
Security

PDF

Create the requested PDF in /workspace. Everything required is preinstalled; never run pip install, npm install, or download dependencies.

Choose the renderer

  • Use WeasyPrint for typography-heavy documents authored naturally as HTML/CSS: resumes, CVs, letters, one-pagers, and styled reports.
  • Use ReportLab for programmatic layouts, drawing, charts, coordinates, or documents assembled directly from Python data.
  • Use A4 unless the user or source context implies US Letter. Use margins of at least 18 mm (0.7 in), 10–11 pt body text, and 1.3–1.5 line height.
  • Available families include DejaVu, Liberation, and Noto (including CJK). Prefer Liberation Sans/Serif for office-style documents and Noto for broad Unicode coverage.
  • Do not embed page numbers, folios, Page X of Y labels, CSS page counters, or numbered ReportLab footers. SurfSense's PDF viewer supplies its own page indicator, so embedded numbering would duplicate the interface.

Escape untrusted text before placing it in HTML.

Converting a file the user already has

When the request is to turn an existing workspace file into a PDF, call load_source_document(path="/documents/...") and convert the source_path it returns. Re-authoring the content with a renderer above would discard the original layout, so reach for it only when the source has no stored upload.

A source that is already a PDF needs no conversion. Convert Office formats with headless LibreOffice, giving each run its own profile directory so concurrent conversions cannot collide, and confirm the output exists before verifying:

soffice --headless -env:UserInstallation=file:///tmp/soffice-<unique> \
  --convert-to pdf --outdir <out-dir> <source_path>

LibreOffice names the output after the source stem, so read it back from <out-dir> rather than assuming your own filename.

Revisions

Start an in-place revision with load_artifact_for_revision. Read its markdown_path for the artifact's substantive content and any other context provided by the user, then regenerate the PDF at expected_output_path. PDF revisions are rebuilds from Markdown/context, not edits inferred from rendered pages. Do not use vision to reconstruct the old PDF; vision may still be used by verify_artifact after regeneration.

Save the verified revision with the returned artifact_id and expected_generation. A changed title, filename, or design is still the same artifact unless the user explicitly asks for a separate copy.

Required quality gate

After generating the requested PDF, call verify_artifact(path=output_path). Warnings are advisory and do not require regeneration. If verification reports blocking findings, fix all blockers together, regenerate once at the same output path, and reverify. If a blocker remains, stop and explain it instead of entering another automatic rewrite loop. Only a verified file can be saved.

Then call save_artifact(path=output_path, title="...", markdown_representation="..."). Working files may use any paths; no source file, preview file, or matching filename stem is part of the publication contract.

The Markdown representation must faithfully contain the document's substantive text so the artifact remains accessible and searchable without parsing the PDF.

Repository
MODSetter/SurfSense
Last updated
First committed

Is this your skill?

If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.