Add specifications for gamification, generation, and R42 chat services
- Introduced gamification service spec detailing responsibilities, API surface, XP calculation, levels, streaks, badges, milestone cards, and heatmap data. - Added generation service spec outlining the process for generating micro learning content, including API endpoints, AI call configuration, prompt strategies, and error handling. - Created R42 chat service spec covering chatbot interactions, retrieval pipeline, prompt construction, response generation, and stateless design principles.
This commit is contained in:
@@ -26,11 +26,16 @@ export async function embedAndStore(
|
||||
writtenTopics: WrittenTopic[],
|
||||
onProgress: (embedded: number) => void,
|
||||
): Promise<void> {
|
||||
// Build chunk → topic mapping
|
||||
// Build chunk → topic mapping.
|
||||
// The AI labels chunks as [CHUNK-<uuid>] so sourceChunkIds may carry that prefix;
|
||||
// strip it so lookups match the bare UUID used as the Qdrant point ID.
|
||||
const normalise = (id: string): string => id.replace(/^CHUNK-/i, '');
|
||||
|
||||
const chunkTopicMap = new Map<string, string>();
|
||||
const chunkThemeMap = new Map<string, string>();
|
||||
for (const topic of writtenTopics) {
|
||||
for (const chunkId of topic.sourceChunkIds) {
|
||||
for (const rawId of topic.sourceChunkIds) {
|
||||
const chunkId = normalise(rawId);
|
||||
chunkTopicMap.set(chunkId, topic.id);
|
||||
chunkThemeMap.set(chunkId, topic.themeId);
|
||||
}
|
||||
@@ -94,7 +99,9 @@ export async function embedAndStore(
|
||||
// Update topics.qdrant_chunk_ids in PocketBase
|
||||
// -------------------------------------------------------------------------
|
||||
for (const topic of writtenTopics) {
|
||||
const qdrantIds = topic.sourceChunkIds.filter(id => chunkTopicMap.get(id) === topic.id);
|
||||
const qdrantIds = topic.sourceChunkIds
|
||||
.map(id => normalise(id))
|
||||
.filter(id => chunkTopicMap.get(id) === topic.id);
|
||||
if (qdrantIds.length > 0) {
|
||||
await updateTopicQdrantIds(topic.id, qdrantIds);
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ function buildUserPrompt(chunks: Chunk[], filename: string, format: DocumentForm
|
||||
async function callClaude(chunks: Chunk[], filename: string, format: DocumentFormat, strict: boolean): Promise<DraftKB> {
|
||||
const response = await anthropic.messages.create({
|
||||
model: MODELS.SONNET,
|
||||
max_tokens: 8000,
|
||||
max_tokens: 16000,
|
||||
temperature: 0,
|
||||
system: SYSTEM_PROMPT,
|
||||
messages: [{ role: 'user', content: buildUserPrompt(chunks, filename, format, strict) }],
|
||||
@@ -76,12 +76,14 @@ async function callClaude(chunks: Chunk[], filename: string, format: DocumentFor
|
||||
try {
|
||||
parsed = JSON.parse(textBlock.text);
|
||||
} catch {
|
||||
console.error(`[structure] JSON parse failed (strict=${strict}), response length=${textBlock.text.length}, stop_reason=${response.stop_reason}`);
|
||||
if (strict) throw new Error('structure_extraction_failed');
|
||||
return callClaude(chunks, filename, format, true);
|
||||
}
|
||||
|
||||
const result = DraftKBSchema.safeParse(parsed);
|
||||
if (!result.success) {
|
||||
console.error(`[structure] Zod validation failed (strict=${strict}):`, JSON.stringify(result.error.issues.slice(0,3)));
|
||||
if (strict) throw new Error('structure_extraction_failed');
|
||||
return callClaude(chunks, filename, format, true);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user