Files
learning-platform/docs/ingestion-spec.md
RaymondVerhoef 07af2783dc
All checks were successful
On Push to Main / test (push) Successful in 1m33s
On Push to Main / publish (push) Successful in 1m31s
On Push to Main / deploy-dev (push) Successful in 2m3s
Add comprehensive documentation for key organizational aspects
- Introduced "Pension Scheme & Benefits" detailing secondary employment benefits and pension specifics.
- Created "Roles & Accountabilities" outlining the Holacracy role structure and responsibilities within Respellion.
- Added "Security" section covering GDPR compliance and workplace safety protocols.
- Established "Spending and Contracting" policy detailing expense categories and submission processes.
- Documented "Who We Are" to define Respellion's identity, services, and operational model under Holacracy and ISO 9001.
2026-05-27 08:24:56 +02:00

73 lines
3.1 KiB
Markdown

# Ingestion spec: source documents → knowledge graph
Turns admin-uploaded text into `topics` and `relations` using Claude. Runs
entirely client-side; there is no ingestion service.
- **UI:** `src/components/admin/UploadZone.jsx` (Admin → Sources tab)
- **Pipeline:** `src/lib/extractionPipeline.js`
- **Tool/schema:** `emit_knowledge_graph` (`src/lib/llmTools.js`) validated by
`extractionResultSchema` (`src/lib/llmSchemas.js`)
---
## Upload
- Accepted formats: **`.txt` and `.md`**, max **5 MB** per file.
- Drag-and-drop or click-to-browse. Unsupported files are skipped with a toast.
- The queue tracks each file: `pending → processing → done / failed / cancelled`.
- Progress is polled every ~2s from the `sources.progress` field
(`{ current, total, message }`), shown as "Chunk N/total".
- **Orphan detection:** sources stuck in `processing` for >5 minutes (e.g. a closed
tab) can be marked failed or deleted.
---
## Pipeline: `processSourceText(textContent, sourceName, { signal })`
1. **Create source record** with `status='processing'`.
2. **Chunk** the text (`chunkText`): target ~8000 chars per chunk with ~800 chars
overlap, splitting on sentence/paragraph boundaries (hard-splitting oversized
sentences). Overlap preserves cross-boundary context.
3. **Known-topics hint** (`buildKnownIdsHint`): up to the 200 most recent existing
topics are listed so the model reuses existing ids instead of duplicating them.
4. **Per-chunk extraction** via `callLLM`:
- tier `standard`, `maxTokens: 8192`, `timeoutMs: 180_000`
- forced `toolChoice` on `emit_knowledge_graph`
- rate-limited (~20 req/min, burst 2) to protect quota across many chunks
- system prompt instructs: ≤15 topics per chunk; topic `type`
{`concept`, `role`, `process`}; `learning_relevance`
{`core`, `standard`, `peripheral`, `exclude`}; relation `type`
{`related_to`, `depends_on`, `part_of`, `executed_by`}
5. **Update progress** before each chunk.
6. **Merge** (`mergeKnowledgeGraph`): topics keyed by `id` (new data updates
existing, but `learning_relevance` is preserved when `relevance_locked` is true);
relations de-duplicated on `(source, target, type)`. Persisted via
`db.saveTopics` / `db.saveRelations`.
7. **Finalize:** `status='completed'`, or `failed` (error) / `cancelled` (abort).
Aborting via the `signal` stops the run and marks the source `cancelled`.
---
## Output shape (`emit_knowledge_graph`)
```json
{
"topics": [ { "id", "label", "type", "description", "learning_relevance" } ],
"relations":[ { "source", "target", "type" } ]
}
```
`theme`, `complexity_weight`, and `difficulty` are **not** set here — they are
added later by the curriculum enrichment step (see `docs/curriculum-spec.md`).
---
## Gotchas
- If extraction logs a truncation (`LLMTruncatedError`, `stop_reason: max_tokens`),
tighten the per-chunk topic cap before raising `max_tokens`.
- A source already `completed` is not re-processed; delete it to force re-analysis.
- There are no embeddings produced here — R42 retrieval is computed at query time
with TF-IDF over `topics`.