Plattform
ScaiWave ScaiGrid ScaiCore ScaiBot ScaiDrive ScaiKey Modelle Tools & Services
Lösungen
Organisationen Entwickler Internet Service Provider Managed Service Provider AI-in-a-Box
Ressourcen
Support Documentation Blog Downloads
Unternehmen
Über uns Forschung Karriere Investieren Kontakt
Anmelden

Changelog

v0.1.2 alpha — July 2026 (in flight)#

Quality pass on the PPTX pipeline, hardening MCP tool schemas, and a long-overdue architectural cleanup: brand themes are now tenant-owned rather than hardcoded into the shipped bundle.

Added#

  • Office-native default theme — new office builtin theme uses Aptos (Microsoft Office 2024+ default) with Calibri fallback and a neutral palette. This is the theme every caller gets when theme is omitted. If the reader doesn't have Aptos installed, the deterministic fallback chain lands on Calibri → Segoe UI → Helvetica Neue → Arial → sans-serif — so decks render the way most readers expect.
  • PPTX layout engine — slide elements now stack sequentially in a theme-declared body zone with heights proportional to estimated content weight, instead of every element rendering at the same fixed (x=0.5, y=1.5, w=9, h=5) rectangle. paragraph + bullet_list on the same slide no longer overlap. Themes carry per-master zones in pptx.masters[] — override defaults per tenant without touching renderer code.
  • paragraph on slides — the docx paragraph element type is now accepted inside slide.elements[]. The renderer parses embedded multi-line markdown, detects lines starting with - / * / / / as real bullets (<a:buChar>) and 1. / 1) as ordered lists (<a:buAutoNum>), and preserves inline **bold** / *italic* on every line including bulleted ones. Content the LLM used to emit as one wall of text now stacks with real bullet indentation.
  • Deck-appropriate slide typography — new optional pptx.typography block on themes overrides docx-derived slide sizes. office ships with slide_title: 36pt / slide_subtitle: 22pt / bullet_body: 18pt — matching Microsoft PowerPoint's stock master defaults.
  • Image elements accept url — as an alternative to asset_ref. When a spec carries {type: image, url: "https://..."}, the worker fetches the URL server-side during finalize, subject to SSRF protection (private/loopback/link-local/metadata IPs blocked, hostname re-checked per redirect hop), a 3-redirect ceiling, 10 s timeout, 20 MB size cap, and an image/* content-type allowlist. Failed fetches surface a labeled placeholder in the render ([image: <alt> — fetch failed: <reason>]) instead of tanking the whole deck. Prefer asset_ref for repeatable renders; url is the "just make it work" convenience path.
  • Asset resolver walks the whole spec — pre-fix, it only descended into spec.body[], silently ignoring every spec.slides[*].elements[] image reference. Now walks body + slides + sheet charts uniformly.
  • Tenant-owned themes — new tenant_themes table stores per-tenant brand themes. resolve_theme checks tenant themes first, then builtins; a tenant asking for a theme that isn't theirs gets a clean 404 theme not found (per §15.3 isolation). scribe_list_themes returns the visible set with each entry stamped scope: "builtin" or scope: "tenant".

Changed#

  • scailabs moved off the builtin bundle — it's now a tenant-registered theme owned by the ScaiLabs tenant. Non-ScaiLabs callers can no longer resolve theme="scailabs" — the error message names the visible set and is marked non-retriable so LLM tool-calling loops break cleanly. Migration path: no action needed for tenants that never referenced scailabs. ScaiLabs-owned docs continue to render unchanged. Third-party docs currently tagged theme="scailabs" will 404 on next re-render — set the theme explicitly or omit it to get the office default.
  • office is now the code default everywhere theme= had a default value: scribe_create, scribe_ingest, scribe_instantiate_template, the corresponding REST routes, template + document services. Callers that already passed a theme explicitly are unaffected.
  • MCP tool schemas advertise additionalProperties: false — strict-mode agents (Mistral Large in strict mode, recent Claude tool-calling) refuse to emit fields the schema doesn't declare, so invented arguments like {queries: [...]} on scribe_create_document no longer make it out of generation. Agents that don't enforce at generation time hit a runtime rejection with a structured, LLM-legible error naming the offending field, listing valid fields, and marked NOT a retriable error to break retry loops.
  • Sharpened format-mismatch errors — the previous "op 'add_element' requires a docx document, not 'pptx'" message trapped LLM agents in retry loops because it didn't point at the correct alternatives. Now: names the doc's actual type, lists the correct ops + MCP tools for that type, marks the failure non-retriable. Same treatment for slide-op-on-docx and sheet-op-on-non-xlsx.
  • Format-specific tool docstrings — every scribe_add_* tool now leads with **DOCX only.** / **PPTX only.** / **XLSX only.** and points at the correct alternative family. Well-behaved LLMs pick the right tool at discovery time instead of hitting a 422.

Fixed#

  • PPTX bullets rendered as literal dashes in slides that came through the paragraph element type. Root cause: bullet: {type: "bullet"} in pptxgenjs is silently no-op (only type: "number" is handled). Switched to bullet: true for default bullet characters — real <a:buChar char="•"/> markers now emit correctly.
  • Slide element overlap on the content master when both a subtitle and a body element were present — the body zone started at y=1.5 while the subtitle occupied y=1.3-1.9. Now zones are non-overlapping by construction.

Operator notes#

  • Migration required: alembic upgrade head applies 0011_tenant_themes which creates the table + seeds the scailabs theme JSON as owned by tnt_tpljy20lf7svct66. Idempotent to re-run.
  • Worker restart recommended — the theme registry is loaded via @lru_cache at worker startup. Long-running workers from before the migration will hold stale theme state until restarted.
  • Docs: Themes and the MCP tool catalogue updated.

v0.1.1 alpha — June 2026 (shipped)#

Iterative hardening on top of v0.1.0. No breaking API changes; existing SDKs work unchanged.

Added#

  • Native DOCX chart emission — chart parts (word/charts/chartN.xml) are now hand-emitted via OOXML post-processing for kinds bar, column, line, pie. Charts open in Word and LibreOffice as editable native charts, with series data preserved. Other kinds (area, scatter, sankey, etc.) still go through the ECharts SVG fallback.
  • Native XLSX chart emission — same coverage matrix; charts anchor to the spec'd cell and reference proper drawing parts.
  • Pandoc-merge DOCX ingest — when pandoc is on the worker host, ingest runs pandoc alongside mammoth to detect footnotes, math, citations, definition lists, and line blocks. Findings surface as structured fidelity warnings (INGEST_PANDOC_FOOTNOTE_DETECTED and friends). No-op when pandoc is absent.
  • Partner quota rollupGET /v1/admin/quotas/partner/{partner_id}?axis=… aggregates usage across every tenant of a partner. Access: superadmin or partner_admin on that specific partner.
  • Per-user quota rollupGET /v1/admin/quotas/tenant/{tenant_id}/users?axis=… breaks down a tenant's usage by acting user. Full coverage for renders_per_day (windowed) and documents_count (via Spec creator); coverage=none for assets_bytes / templates_count (model has no created_by on those tables yet).
  • PPTX layout-to-theme-master matching on ingest — slide layouts now recover via OOXML <p:cSld name> / <p:sldLayout type> against the theme registry instead of always defaulting to "content".
  • HTML preview for PPTX/XLSX — wraps per-page Gotenberg PNGs into a self-contained HTML preview file.
  • OOXML §4.7 breadcrumbs — round-trip equivalence now covers code_block, callout, and page_break on the slow path (when the JSON breadcrumb is absent).
  • PPTX and XLSX templates (Tier 1) — register a .pptx or .xlsx with {{ var }} placeholders, instantiate via POST /v1/documents/from_template. Same {{ … }} syntax as DOCX; same dotted-path resolution. Plain substitution only — FOR/IF/JS-expressions are DOCX-only via docx-templates. Missing variables in PPTX/XLSX render as empty + emit a TEMPLATE_VARIABLE_MISSING warning instead of erroring (partial fills are common).
  • Templates admin UI — new Templates page in the admin SPA at /admin/templates lists every registered template across the tenants you can see, with per-row expansion showing variable + grammar-token breakdown. Scope: superadmin (all), partner_admin (their partners' tenants), tenant_admin (own tenant only). Backed by the new GET /v1/admin/templates endpoint.
  • PPTX + XLSX template Tier 2 — FOR loops + IF conditionals + a safe JS-flavoured expression evaluator now ship in PPTX and XLSX templates. PPTX gets text-frame-level FOR (replicate paragraphs within a shape) AND slide-level FOR (clone whole slides per item, rewiring rels + content-types + presentation.xml). XLSX gets row-level FOR with row renumbering and relative-cell-ref rewriting in formulas. The expression evaluator is a recursive-descent parser (no eval, no VM) with a per-type method allowlist — supports {{ amount.toFixed(2) }}, {{ name.toUpperCase() }}, ternaries, arithmetic, comparisons. Method calls outside the allowlist render empty + emit a TEMPLATE_EXPRESSION_ERROR warning.
  • Groups admin surface — new Groups page in the admin SPA at /admin/groups browses every ScaiKey group across the tenants you can see. Per-row expansion shows direct + transitive members, parent-group + child-group context. User detail (Users → Roles drawer) now also surfaces the user's group memberships. Backed by three new endpoints: GET /v1/admin/groups, GET /v1/admin/groups/{id}, GET /v1/admin/users/{id}/groups. Read-only — group lifecycle stays in ScaiKey; ScaiScribe mirrors via the daily sync.
  • Per-user job isolation (security) — the non-admin GET /v1/jobs and GET /v1/jobs/{id} now scope strictly to submitted_by == caller. A mortal user in a tenant where colleagues handle sensitive content no longer sees colleagues' job history or result payloads. Migration 0010 adds the submitted_by column on jobs; new jobs stamp it from the auth context at creation. Pre-migration rows (submitted_by IS NULL) are inaccessible via the non-admin endpoints — they only show up in the admin endpoint. Cross-user visibility for operators is unchanged via /v1/admin/jobs.
  • /v1/admin/me enriched — now also returns tenant_name, partner_name, and effective_roles (a structured view of the caller's superadmin / tenant_admin / partner_admin grants). The admin SPA uses effective_roles to filter sidebar nav so users don't see menu items for endpoints they can't reach. The backend STILL enforces 403 on every endpoint regardless of what the SPA renders.
  • Templates upload / download / delete from the admin UI — operators can now register templates on behalf of any tenant in their scope, download the source binary, and soft-delete templates directly from the Templates page. Three new endpoints: POST /v1/admin/templates (multipart upload with tenant_id form field; counts against the target tenant's templates_count quota), GET /v1/admin/templates/{id}/download (presigned URL, or download_url: null for the file backend), GET /v1/admin/templates/{id}/file (direct stream — the fallback when presigning isn't supported), and DELETE /v1/admin/templates/{id} (soft-delete; binary stays in storage). Authorization: superadmin on any tenant, partner_admin on tenants under their partner, tenant_admin on their own tenant.
  • SDKs updated to 0.1.0-alpha.2 — Python (sync + async), TypeScript, and .NET all gain the seven new endpoints from this iteration: cross-tenant template listing/upload/download/delete, groups listing/detail/user-groups. AdminMe now also carries tenant_name, partner_name, and effective_roles (structured is_superadmin / tenant_admin_on / partner_admin_on). The main client gets list_jobs() / listJobs() / ListJobsAsync() (non-admin tenant-scoped, strict per-user isolation) and delete_template() / deleteTemplate() / DeleteTemplateAsync(). Artifacts live at scailabs.ai/downloads.
  • MCP — two new scribe_* tools (44 → 46): scribe_list_jobs (enumerate your pending/recent jobs without remembering IDs) and scribe_delete_template (clean up templates you registered during experimentation). The non-admin DELETE /v1/templates/{id} endpoint backs the new tool — any authenticated user can delete a template in their own tenant.

Changed#

  • Chart slow-path recovery and TOC slow-path recovery formally reclassified as fast-path-only by design (the JSON breadcrumb covers ScaiScribe-authored docs; externally-authored docs degrade gracefully with documented fidelity warnings). Not deferrals — closed by design.

Operator notes#

  • Run alembic upgrade head against your MariaDB to pick up the quota_periods_user table (migration 0009).
  • Install pandoc (apt install pandoc) on the ingest worker hosts to enable the merge audit.

v0.1.0 alpha — June 2026#

First public alpha. Authenticate against ScaiKey, render DOCX / PPTX / XLSX from a JSON spec, ingest existing DOCX, plus a SolidJS admin UI at /admin/.

What works#

  • REST API (19 endpoints) — documents, jobs, assets, fonts, templates, health.
  • MCP server (42 scribe_* tools) — the primary surface for AI agents.
  • Three official SDKs:
    • Python 0.1.0a1 (scaiscribe on PyPI) — sync + async clients.
    • TypeScript 0.1.0-alpha.1 (@scaiscribe/sdk on npm) — single async client; Node 20+ and browsers.
    • .NET 0.1.0-alpha.1 (ScaiLabs.ScaiScribe on NuGet) — .NET 8+.
  • Admin SPA + sub-client — operator surface for jobs / users / roles / tenants / partners.
  • ScaiKey integration — full identity sync, OAuth Authorization Code for the admin UI, OAuth client_credentials for service-to-service.
  • Themesscailabs and per-tenant themes, with single-level extends inheritance and a compilation cache.
  • Templatesdocx-templates placeholder fill via from_template.
  • Ingestion — DOCX, PPTX, XLSX with fidelity scoring and structured warnings.
  • PDF rendering via Gotenberg.

What works (correcting earlier draft)#

These are shipped and have fixture coverage — they were misclassified as deferred in the initial alpha changelog draft:

  • Chart rendering via ECharts SSR — DOCX charts embed as <w:drawing> SVG images, XLSX charts use exceljs.addImage, PPTX uses native pptxgenjs.addChart. The "native chart XML" (chart data lives in the workbook) variant for DOCX/XLSX is the remaining v1.x roadmap item.
  • HTML preview for DOCX — mammoth-based HTML pipeline.
  • Per-page screenshots — PDF + pdftoppm.

Known deferrals (v1.x)#

These are honest gaps, not silent omissions — every relevant code path emits a structured warning. Many of these closed in v0.1.1 (see above).

  • OCR ingestion — no image-to-text yet.
  • ScaiSign / ScaiCMS bridges — integrations come with those products.

Breaking changes#

None — this is the initial release.

Caveats#

  • Pin SDK versions during alpha. Minor breaking changes possible through v1.0 GA.
  • The spec format is at schema_version: "0.1". Migration policy starts at v1.0.
Updated 2026-07-03 13:00:09 View source (.md) rev 16