feat: implement R42 chat infrastructure with Anthropic API integration and custom design system
This commit is contained in:
110
src/components/chat/prompts.js
Normal file
110
src/components/chat/prompts.js
Normal file
@@ -0,0 +1,110 @@
|
||||
/**
|
||||
* R42 — system prompts, greeting, and the propose_graph_delta tool spec.
|
||||
* All user-facing strings live here so they can be localised in one place.
|
||||
*/
|
||||
|
||||
export const BOT_NAME = 'R42';
|
||||
|
||||
export const STRINGS = {
|
||||
greeting: (name) =>
|
||||
`Hoi ${name}, ik ben R42 — vraag iets over je weekonderwerp, of laat me uitleggen wat je in de quiz tegenkwam.`,
|
||||
placeholder: `Vraag R42 iets…`,
|
||||
send: 'Stuur',
|
||||
status: 'online · antwoordt direct',
|
||||
errorGeneric: 'Sorry, ik kon dat niet beantwoorden. Probeer het nog eens.',
|
||||
errorNoKey: 'Er is geen API-sleutel ingesteld. Vraag een beheerder om hem toe te voegen in Admin → Settings.',
|
||||
suggestionTitle: 'Ik hoorde iets nieuws — voeg toe aan de kennisgraaf?',
|
||||
suggestionAccept: 'Ja, voeg toe',
|
||||
suggestionReject: 'Nee, sla over',
|
||||
suggestionAppliedAdmin: 'Toegevoegd aan de graaf.',
|
||||
suggestionQueuedUser: 'Genoteerd — ik geef het door aan een beheerder.',
|
||||
suggestionDismissed: 'Oké, niets gedaan.',
|
||||
closeAria: 'Sluit chatvenster',
|
||||
openAria: 'Open R42 chatbot',
|
||||
};
|
||||
|
||||
export function buildSystemPrompt({ userName, isAdmin, kbContext }) {
|
||||
return [
|
||||
`Je bent R42, de chatbot-avatar van Respellion — een leerplatform voor microlearning, quizzen en kennisontwikkeling.`,
|
||||
`Antwoord altijd in het Nederlands, kort en zakelijk-vriendelijk. Spreek de gebruiker aan met hun voornaam wanneer dat natuurlijk voelt (${userName}).`,
|
||||
``,
|
||||
`JE TAKEN:`,
|
||||
`1. Leg onderwerpen uit die in de kennisbasis staan.`,
|
||||
`2. Help de gebruiker quizvragen begrijpen ná afloop (niet tijdens een actieve quiz).`,
|
||||
`3. Verwijs bij twijfel terug naar het bronmateriaal of zeg eerlijk dat je het niet weet.`,
|
||||
``,
|
||||
`JE KENNIS:`,
|
||||
`Je kennis is beperkt tot de onderstaande Respellion-kennisgraaf. Als een vraag duidelijk buiten dit bereik valt, zeg dat dan eerlijk en stel voor dat de gebruiker de bron toevoegt via Admin → Sources.`,
|
||||
``,
|
||||
kbContext,
|
||||
``,
|
||||
`KENNISGRAAF VERFIJNEN:`,
|
||||
`Wanneer de gebruiker iets noemt dat duidelijk een nieuw topic, nieuwe relatie, proces of rol is — en dat nog niet in de kennisgraaf staat — gebruik dan de tool "propose_graph_delta" om een voorstel te maken. Verzin niets: stel alleen iets voor als de gebruiker het concreet noemt. Stel maximaal 3 topics en 5 relaties per beurt voor.`,
|
||||
``,
|
||||
`STIJL:`,
|
||||
`- Houd antwoorden onder de 4 zinnen tenzij de gebruiker om uitleg vraagt.`,
|
||||
`- Geen markdown-headers; gewone Nederlandse tekst.`,
|
||||
`- Bij onzekerheid: "Ik weet het niet zeker — controleer dit in het handboek."`,
|
||||
isAdmin
|
||||
? `\nDe gebruiker is beheerder; voorstellen die de tool genereert worden direct toegepast.`
|
||||
: `\nDe gebruiker is geen beheerder; voorstellen worden in een goedkeuringswachtrij gezet.`,
|
||||
].join('\n');
|
||||
}
|
||||
|
||||
export const PROPOSE_GRAPH_DELTA_TOOL = {
|
||||
name: 'propose_graph_delta',
|
||||
description:
|
||||
'Stel toevoegingen aan de Respellion-kennisgraaf voor wanneer de gebruiker een topic, proces, rol of relatie noemt die nog niet bestaat. Gebruik dit alleen wanneer je iets nieuws en concreets hoort — niet voor algemene speculatie.',
|
||||
input_schema: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
reason: {
|
||||
type: 'string',
|
||||
description: 'Korte uitleg (1 zin, NL) waarom dit voorstel relevant is.',
|
||||
},
|
||||
topics: {
|
||||
type: 'array',
|
||||
description: 'Maximaal 3 nieuwe topics.',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
id: {
|
||||
type: 'string',
|
||||
description: 'kebab-case identifier, bv. "onboarding-buddy".',
|
||||
},
|
||||
label: {
|
||||
type: 'string',
|
||||
description: 'Mens-leesbare naam.',
|
||||
},
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['concept', 'role', 'process'],
|
||||
},
|
||||
description: {
|
||||
type: 'string',
|
||||
description: '1–2 zinnen Nederlandstalige beschrijving.',
|
||||
},
|
||||
},
|
||||
required: ['id', 'label', 'type', 'description'],
|
||||
},
|
||||
},
|
||||
relations: {
|
||||
type: 'array',
|
||||
description: 'Maximaal 5 nieuwe relaties.',
|
||||
items: {
|
||||
type: 'object',
|
||||
properties: {
|
||||
source: { type: 'string', description: 'topic id' },
|
||||
target: { type: 'string', description: 'topic id' },
|
||||
type: {
|
||||
type: 'string',
|
||||
enum: ['related_to', 'depends_on', 'part_of', 'executed_by'],
|
||||
},
|
||||
},
|
||||
required: ['source', 'target', 'type'],
|
||||
},
|
||||
},
|
||||
},
|
||||
required: ['reason'],
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user