Skip to content

[Feat] Community Local: Studio — generate artifacts from your documents - #1753

Merged
CREDO23 merged 18 commits into
MODSetter:devfrom
CREDO23:feat/local-studio
Sep 7, 2026
Merged

[Feat] Community Local: Studio — generate artifacts from your documents#1753
CREDO23 merged 18 commits into
MODSetter:devfrom
CREDO23:feat/local-studio

Conversation

@CREDO23

@CREDO23 CREDO23 commented Sep 7, 2026

Copy link
Copy Markdown
Collaborator

Adds Studio to the community local app: pick documents, pick a format, get a grounded artifact. Built on the existing document/ingestion/LLM stack — an artifact is a Document, so it rides search and freshness like any source.

What you can make

  • Documents (model-authored code): docx, pptx, xlsx, pdf
  • Structured: summary, HTML doc, mind map, flashcards, quiz
  • Podcast: two-host script, synthesised offline with Kokoro-82M (WAV), bundled by default
  • Visual: image, infographic — BYO OpenRouter key, gated when no key is set

How it works

The worker runs gather → generate → render → persist, streaming status to the UI over the existing SSE path. Every format routes to exactly one of three peer families over a shared contract (artifact, builder, text); an invariant test asserts the partition.

  • office/ — for docx/pptx/xlsx/pdf the model writes the Python (python-docx, python-pptx, xlsxwriter, reportlab) and the worker runs it in-process with a timeout. Unsandboxed by design: a local, single-user app. Each format is a folder with its own SKILL.md of authoring craft.
  • builders/ — the deterministic formats: the model emits structured markdown/JSON and a trusted per-format builder renders it.
  • media/ — podcast (transcript + nested offline Kokoro TTS) and visual (BYO OpenRouter image model).

UI: a dialog off the Sources panel to create, browse, and view artifacts; audio and images render inline.

Tests

Backend unit + integration suites (deterministic builders, office code-execution, media, and pipeline routing) and the frontend studio suite pass.

High-level PR Summary

This PR adds Studio to the community local app, enabling users to generate artifacts (summaries, Office files, PDFs, podcasts, images, study aids) from their workspace documents. The implementation uses a deterministic builder architecture where LLMs emit structured content (JSON/markdown) and trusted Python functions render files using standard libraries (python-docx, python-pptx, XlsxWriter, fpdf2), avoiding LLM-authored code execution and sandboxing. Artifacts are stored as ARTIFACT documents that integrate with the existing search and indexing infrastructure. The feature includes 10 text/Office formats with local builders, offline podcast synthesis via Kokoro-82M (optional), and visual formats (image/infographic) that route to a BYO OpenRouter model. The UI provides a dialog off the Sources panel for creation, browsing, and viewing artifacts with inline rendering for audio and images. The entire feature ships with comprehensive test coverage (165 backend tests, frontend suite) and detailed planning documentation.

⏱️ Estimated Review Time: 3+ hours

💡 Review Order Suggestion
Order File Path
1 docs/adr/0003-artifacts-as-documents.md
2 plans/community-local/00-umbrella-plan.md
3 plans/community-local/api/04-studio.md
4 plans/community-local/worker/04-studio.md
5 plans/community-local/frontend/04-studio.md
6 surfsense_local/backend/modules/artifacts/formats.py
7 surfsense_local/backend/modules/artifacts/models.py
8 surfsense_local/backend/modules/artifacts/schemas.py
9 surfsense_local/backend/modules/artifacts/service.py
10 surfsense_local/backend/modules/artifacts/dependencies.py
11 surfsense_local/backend/modules/artifacts/tasks.py
12 surfsense_local/backend/modules/artifacts/router.py
13 surfsense_local/backend/worker/studio/builders/types.py
14 surfsense_local/backend/worker/studio/builders/util.py
15 surfsense_local/backend/worker/studio/builders/summary.py
16 surfsense_local/backend/worker/studio/builders/docx.py
17 surfsense_local/backend/worker/studio/builders/pptx.py
18 surfsense_local/backend/worker/studio/builders/xlsx.py
19 surfsense_local/backend/worker/studio/builders/html_doc.py
20 surfsense_local/backend/worker/studio/builders/pdf.py
21 surfsense_local/backend/worker/studio/builders/mindmap.py
22 surfsense_local/backend/worker/studio/builders/flashcards.py
23 surfsense_local/backend/worker/studio/builders/quiz.py
24 surfsense_local/backend/worker/studio/builders/podcast.py
25 surfsense_local/backend/worker/studio/builders/__init__.py
26 surfsense_local/backend/worker/studio/tts.py
27 surfsense_local/backend/worker/studio/visual.py
28 surfsense_local/backend/worker/studio/gather.py
29 surfsense_local/backend/worker/studio/generate.py
30 surfsense_local/backend/worker/studio/persist.py
31 surfsense_local/backend/worker/studio/pipeline.py
32 surfsense_local/backend/worker/studio/__init__.py
33 surfsense_local/backend/worker/notify.py
34 surfsense_local/backend/api/main.py
35 surfsense_local/backend/shared/config.py
36 surfsense_local/backend/shared/queue.py
37 surfsense_local/backend/pyproject.toml
38 surfsense_local/backend/scripts/fetch_kokoro_model.py
39 surfsense_local/backend/bundling/worker.spec
40 surfsense_local/backend/modules/events/schemas.py
41 surfsense_local/backend/uv.lock
42 surfsense_local/frontend/src/features/studio/api.ts
43 surfsense_local/frontend/src/features/studio/use-studio.ts
44 surfsense_local/frontend/src/features/studio/studio-dialog.tsx
45 surfsense_local/frontend/src/features/sources/sources-panel.tsx
46 surfsense_local/frontend/src/features/dashboard/dashboard-page.tsx
47 surfsense_local/frontend/src/lib/api.ts
48 surfsense_local/backend/tests/unit/worker/test_studio_builders.py
49 surfsense_local/backend/tests/unit/worker/test_studio_visual.py
50 surfsense_local/backend/tests/integration/artifacts/test_routes.py
51 surfsense_local/backend/tests/integration/worker/test_studio.py
52 surfsense_local/frontend/src/features/studio/studio-dialog.test.tsx

Need help? Join our Discord

LLM emits structured content, a trusted per-format builder renders it, and
the result persists as an ARTIFACT document + artifacts sidecar. Ships the
summary format end to end: worker studio pipeline (gather/generate/build/
index), the artifacts API (studio jobs, list, detail, file, delete), the
studio_job task, and an artifacts SSE event kind.
A Studio dialog off the Sources header: pick a format, pick indexed sources,
optional prompt, Generate. Artifacts list with live status (poll while
running), a viewer for the rendered body, and per-file downloads for later
formats.
…/flashcards/quiz (phase 4b)

Each format prompts the model for a JSON spec and renders it with a trusted
per-format function: python-docx/pptx and XlsxWriter for Office files, an
escaped template for HTML, and markdown projections for mind maps, flashcards
and quizzes. json parsing tolerates fenced/prose-wrapped output. The frozen
worker bundles the docx/pptx templates and registers the studio task.
markdown-spec -> PDF via pure-Python fpdf2 (no Pango/Cairo system libs to
bundle). Uses an on-disk Unicode TTF when present, else Helvetica with a
Latin-1 fallback; a bundled font pack is the upgrade path.
@vercel

vercel Bot commented Sep 7, 2026

Copy link
Copy Markdown

@CREDO23 is attempting to deploy a commit to the Rohan Verma's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Team

Run ID: c89fa8e2-7d1a-4196-8fc3-a61f7c9935e4

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CREDO23 CREDO23 changed the title feat(local): Studio — generate artifacts from your documents [Feat] Community Local: Studio — generate artifacts from your documents Sep 7, 2026
…ed office code

- office/ writes docx/pptx/xlsx/pdf as model-authored code (spec + SKILL.md per
  format, shared prompt/runner), replacing the deterministic builders for those
  formats; generate.run_model is the shared model call.
- media/ groups the audio/visual family: podcast (transcript builder + nested
  Kokoro tts) and visual (BYO OpenRouter image/infographic).
- builders/ keeps the deterministic formats (summary/html/mindmap/flashcards/quiz).
- Shared contract lifted to studio root (artifact.py, builder.py, text.py) so the
  three families are peers, none importing from a sibling.
- pipeline routes every catalog key to exactly one family; an invariant test
  asserts the partition.
The model now authors PDF code; reportlab is pure-Python and bundles cleanly,
matching the cloud PDF skill. fpdf2 is no longer used.
# Conflicts:
#	surfsense_local/frontend/src/features/sources/sources-panel.tsx
Parametrize the worker pipeline test over the whole Studio catalogue so all
twelve formats run their real builder/office-code/media path to a ready
artifact, faking only the model (plus podcast TTS and the image API). Drops the
two single-format cases now subsumed by the matrix.
Replace the parametrized matrix with a named test per format, each documenting
what that format produces and asserting the optional user prompt reaches the
model. Still fakes only the model (plus podcast TTS and the image API); the
builders, office code runner, and persistence run for real.
Resolve the model's inline [n] against the sources it was given: an ordinal
with no source is dropped rather than left dangling, and the survivors are
renumbered densely by first appearance so the stored turn and its listed
sources agree. Ordinals inside code spans pass through untouched. The stream
now stores and emits only the sources actually cited.
Unit tests for normalize_citations: invented ordinals dropped and survivors
renumbered, a repeated source maps to one number, ordinals inside code spans
are left alone, and the empty cases.
@CREDO23
CREDO23 merged commit bba6675 into MODSetter:dev Sep 7, 2026
4 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant