Naar de inhoud
Docxcelerate

Basis

Statisch en dynamisch

Wat op je eigen machine wordt opgelost, wat de engine nodig heeft, en waarom de grens ligt waar hij ligt.

Elke contentnode is ofwel statisch ofwel dynamisch. Dat onderscheid bepaalt waar zijn tekst vandaan komt en wat hij kost.

Je declareert het nooit zelf. Er is één helper per soort, en de modus volgt uit de opties die je meegeeft.

Statische nodes

Geef een alinea een render en hij kan uit je data worden geproduceerd, dus hij wordt lokaal opgelost:

paragraph<OfferData>({
  id: "offer",
  render: (data) =>
    `Your place starts on ${data.startDate}, at ${data.college}.`,
});

Hij draait in de preview, in tests en in een build — offline, direct, gratis. Als elke node in een document statisch is, heb je de engine helemaal niet nodig.

Dynamische nodes

Geef hem in plaats daarvan prompts, plus een placeholder zodat de preview leesbaar blijft, en hij wordt dynamisch:

paragraph<OfferData>({
  id: "tutor-note",
  placeholder: (data) => `A note from ${data.interviewer}.`,
  generalPrompt: (data) =>
    `Write two warm sentences about ${data.applicantName}'s interview.`,
});

Dezelfde helper, andere verplichtingen. image en graph werken op dezelfde manier — src en data zijn daar de leden voor lokale oplossing.

Waarom het wordt afgeleid

Een node met een render kan altijd lokaal worden geproduceerd; een node met alleen prompts nooit. De modus naast die opties declareren zou een tweede bron van waarheid zijn die het met die opties oneens kan zijn — een staticParagraph met een generalPrompt, of andersom, met een of andere voorrangsregel die bepaalt wie wint.

In plaats daarvan zijn de opties de waarheid en wordt mode daaruit afgeleid. Zowel een render als een generalPrompt meegeven is een compileerfout, geen kop-of-munt tijdens runtime.

mode bestaat nog steeds in het gebouwde DocumentModel en in document.json — de engine moet weten welke nodes hij moet oplossen. Het is uitvoer, geen invoer.

Er zijn vier promptslots beschikbaar. Alleen generalPrompt is verplicht:

SlotDoel
generalPromptWat de node moet zeggen
infoPromptContext die het model moet hebben maar niet moet herhalen
negativePromptWat vermeden moet worden
systemPromptInstructies over rol en toon

Wat je lokaal ziet

Bouwen voor de preview lost dynamische nodes op naar hun placeholders, niet naar gegenereerde tekst:

const document = await buildProjectPreviewDocument(project);
// dynamic nodes -> placeholder text

Dat is met opzet zo. De preview blijft deterministisch en gratis, zodat je aan structuur en opmaak kunt werken zonder dat er ook maar één verzoek je machine verlaat. De placeholder is ook een nuttige discipline: als een document met placeholders onleesbaar is, doet zijn structuur te weinig werk.

Wat er op het moment van de aanvraag gebeurt

Het uploadartefact bewaart waarden voor het aanvraagmoment als tokens zoals {{data.residentName}}, zodat ze later kunnen worden opgelost. Als je het naar de engine stuurt, krijg je het voltooide document terug met de dynamische nodes ingevuld.

De engine is een aparte, gratis dienst die je zelf host — hij maakt bewust geen deel uit van het npm-package, zodat het installeren van het framework nooit iets binnenhaalt dat API-sleutels of een netwerk wil. Laat een workspace naar die van jou wijzen:

dxcl init my-documents --api-endpoint https://documents.example.com/api/letters
dxcl init my-documents --no-api-endpoint

Je kunt upload.endpoint in docxcelerate.config.json op elk moment wijzigen.

Waarom de grens hier ligt

Door op de node te splitsen in plaats van op het document blijft de gratis helft van de toolkit echt bruikbaar. Een volledig statisch document is een compleet, werkend document zonder dienst erachter. Je kiest alleen voor de gehoste helft voor precies die alinea’s die gegenereerde tekst nodig hebben — en je kunt aan het template aflezen welke dat zijn.


Deze pagina bewerken op GitHub ↗