@plesso/content-factory
v0.1.0
Published
AI article drafter for editorial-grade content sites. Markdown→PortableText, deterministic internal-link suggester (re-exported from @plesso/sanity-seo), Anthropic-backed drafter with prompt/budget telemetry, Slack notifier, framework-agnostic HTTP handle
Maintainers
Readme
@plesso/content-factory
AI article drafter for editorial-grade content sites built on Sanity. Pairs with @plesso/sanity-seo — content-factory produces drafts; sanity-seo validates and tracks them.
Status
Phase 4.4 — sources lifted. All libraries, scripts, and Vercel-edge HTTP handlers are in src/. The package builds in isolation. Phase 4.3 (next session) switches surprisemywife to consume both @plesso/sanity-seo and @plesso/content-factory via published npm packages.
What ships here
Pure libraries (lib/)
draftArticle(args)— the drafter. Calls Anthropic (model + prompt + temperature from args), parses the response into Markdown, converts to Portable Text, scores + inserts internal links via@plesso/sanity-seo/lib/suggestLinks, returns a complete draft object ready forcommitDraft. Includes prompt template hydration, per-call telemetry capture, monthly budget caps.commitDraft(client, draft, opts)— writes the draft to Sanity as a draft document. Idempotent on the draft ID.isClusterDue(cluster)+isOverMonthlyBudget(cluster)— schedulers. Plain functions; no I/O.markdownToPortableText(md)+portableTextToPlain(pt)— bidirectional. The Markdown parser is intentionally small; assumes the model output stays within the prompt's stylistic bounds.notifySlack(payload, opts)— webhook ping for new drafts. Resilient: failures log and continue.
HTTP handlers (api/)
Framework-agnostic. Each handler takes a Web Request and returns a Response. Wire them into your runtime of choice.
api/draft— single-draft endpoint. POST with cluster ID + topic. Returns the committed draft ID.api/scheduled-run— cron walker. GET (with Vercelx-vercel-cronheader OR a shared secret) iterates every enabled cluster, drafts the ones whose cadence is due and budget allows. Aggregate report in response body.
CLI scripts (scripts/)
factory-draft.mjs— local trigger fordraftArticle. Loads.env.local, picks a cluster + queue item, drafts, prints the result. Use for one-off experiments without redeploying the edge endpoint.seed-content-factory.mjs— idempotently creates a defaultpromptTemplateand a startertopicalCluster(both schemas live in@plesso/sanity-seo). Run once after wiring sanity-seo's schemas into your Studio.
Install (Phase 4.3 onward)
pnpm add @plesso/content-factory @plesso/sanity-seoRequired peers:
@sanity/client>=6.22@plesso/sanity-seo(any version)
Usage sketch
A minimal Vercel edge function that re-exports the scheduled-run handler:
// api/factory/scheduled-run.js (in your consumer app)
export {default} from '@plesso/content-factory/api/scheduled-run'Programmatic use of the drafter:
import {draftArticle, commitDraft} from '@plesso/content-factory/lib/draft-article'
import {createClient} from '@sanity/client'
const client = createClient({projectId, dataset, token, apiVersion: '2024-01-01'})
const cluster = await client.getDocument('topicalCluster.anniversary-gifts')
const draft = await draftArticle({
cluster,
topic: cluster.queue[0],
anthropicKey: process.env.ANTHROPIC_API_KEY,
})
await commitDraft(client, draft)What this package does NOT do
- No Studio UI. The drafter is a backend pipeline; if you want editor-triggered actions (Generate Meta from Body, Compute Readiness, etc.) those live in
@plesso/sanity-seo/actions. - No knowledge intake. The drafter assumes you have a topical cluster + prompt template already populated. The chat agent that produces those is
@plesso/knowledge-intake(Phase 5+). - No methodology routing. Drafter assumes the prompt template encodes whatever style/structure you want. Methodology selection happens upstream in
@plesso/methodology(Phase 5+).
License
UNLICENSED for now. Will likely move to MIT alongside the rest of the @plesso/* set once we're ready to open-source the engine layer (separate from the Plesso platform).
