@edugate/authoring
v0.8.0
Published
Gli strumenti con cui un modello compone contenuto Edugate: il flusso guidato, la tela, i prefab, il builder su MCP e gli specialisti.
Keywords
Readme
@edugate/authoring
Ciò che serve a un modello per comporre contenuto per Edugate — una sorgente sola, tre host.
Questi tool vivevano dentro un gateway fuori dal monorepo. Copiarli dentro
apps/api avrebbe risolto la richiesta e ne avrebbe creata una peggiore: due
copie da modificare insieme per sempre, e la prima volta che qualcuno ne tocca
una sola divergono in silenzio — perché nessun compilatore le mette a confronto.
Qui non sono una copia: sono la sorgente.
packages/authoring/
├── ./flow i quindici tool: dodici `activity_*` (2D e 3D) e tre `builder_*`
├── ./canvas le operazioni della tela e il loro vocabolario
├── ./prefabs i quarantanove blocchi preconfezionati
├── ./builder i tre tool che aprono e modificano un'attività esistente
└── ./agents prompt, allowlist e card dei sette specialisti
│
├── apps/api li monta in processo (POST /mcp)
└── edugate-agents l'ospite per Dify⚠️ Non c'è un export root: si importa sempre un sottopercorso. L'esecutore
degli specialisti non è qui — sta in @edugate/ai-engine; qui ci sono le loro
DEFINIZIONI.
Montarlo
import { createAuthoringTools, InMemoryDraftStore } from "@edugate/authoring/flow";
const tools = createAuthoringTools({
clientFor: async (ctx) => clientBoundTo(ctx), // ← l'identità è tua
drafts: new InMemoryDraftStore(),
searchImages, // ← opzionale
});
for (const tool of tools) {
server.registerTool(tool.name, {
title: tool.title,
description: tool.description,
inputSchema: tool.inputSchema,
}, async (params) => {
const envelope = await tool.run(params, ctx);
return {
structuredContent: envelope,
content: [{ type: "text", text: envelopeToText(envelope) }],
};
});
}Il pacchetto restituisce dati. structuredContent è il contratto tipizzato
per il modello, il testo è per gli host che leggono ancora content[0].text, e
disegnarli su una tela è una decisione dell'host — non una di queste.
Le porte, e perché sono porte
ports.ts le documenta per esteso. In breve:
| porta | cosa decide | perché non è nel pacchetto |
|---|---|---|
| clientFor(ctx) | con quale identità si scrive su Edugate | nel gateway si scambia un token OAuth; nell'API il chiamante è già noto e non c'è nulla da scambiare |
| drafts | dove vivono i documenti fra activity_draft e activity_save | un processo solo può tenerli in memoria; più repliche no |
| searchImages | come si cercano le immagini | è una capacità pura, e vive in @edugate/media: la si passa, non la si incorpora |
| sceneRuntimes | quali motori sanno disegnare una scena | è l'ELENCO, e sta nel registro. L'ORDINE in cui provarli è una politica e sta qui, in scene/engines.ts |
| sceneDrafts | dove vivono i documenti fra activity_draft3d e activity_save3d | stessa ragione di drafts, e per il 3D è stata aggiunta DOPO: senza, un ospite che ricostruisce i tool a ogni richiesta perdeva ogni bozza |
| mirrorImages | dove finiscono le immagini copiate dentro Edugate | il pacchetto sa DECIDERE cosa copiare e sa scaricarlo; dove si depositi è di chi lo ospita |
Assente searchImages, activity_images risponde «capacità non configurata» — una
diagnosi, mai zero risultati in silenzio, che somiglia a «non esiste nulla su
questo argomento» ed è una risposta diversa e falsa.
I nomi dei tool sono un contratto
2D: activity_mode, activity_catalog, activity_create, activity_draft,
activity_images, activity_save. 3D: activity_create3d,
activity_templates3d, activity_models3d, activity_textures3d,
activity_draft3d, activity_save3d. Builder: builder_open,
builder_tools, builder_apply.
Un modello che ha imparato activity_create smette di trovarlo se lo si
rinomina, quindi questi nomi non si toccano alla leggera. È già successo una
volta di proposito: configure_quiz_poll è diventato configure_quiz perché
Poll non è un tipo di blocco della piattaforma e il vecchio nome prometteva a
un modello una cosa che non esiste. Ogni configurazione Dify già costruita è
andata cambiata a mano.
Cosa NON fa
Non pubblica. Salva bozze private e si ferma lì. La pubblicazione di Edugate non è gated sulla moderazione — è il proprietario che rende pubblica la propria attività — e proprio per questo un tool non può farla: uno schema valido non è un fatto vero, e un quiz con una data sbagliata passa ogni validazione e arriva a una classe.
Non valida. parseContent e checkConsumes vivono in @edugate/types e
sono l'unica implementazione; qui si chiama l'host. Senza validazione
raggiungibile non si inventa un «valido» locale: si dice che non è disponibile e
non si offre il salvataggio.
Non ha un LLM dentro. Il modello è quello del client. Qui arrivano dati.
