claritykit-svelte
Version:
A comprehensive Svelte component library focused on accessibility, ADHD-optimized design, developer experience, and full SSR compatibility
201 lines (200 loc) • 7.37 kB
JavaScript
/**
* Convert a chat message to a knowledge block
*/
export function messageToKnowledgeBlock(message) {
const content = typeof message.content === 'string'
? message.content
: message.content.text || message.content.html || '';
return {
id: message.metadata?.blockId || `msg-${message.id}`,
content,
type: 'message',
metadata: {
created: new Date(message.timestamp),
modified: message.metadata?.editedAt ? new Date(message.metadata.editedAt) : new Date(message.timestamp),
author: message.sender.id,
tags: message.metadata?.semanticTags || [],
links: message.metadata?.blockLinks || [],
backlinks: [] // Would be populated by the knowledge system
}
};
}
/**
* Extract semantic concepts from message content
*/
export async function extractSemanticConcepts(content) {
// This would integrate with the actual knowledge system/AI
// For now, return mock concepts based on simple keyword matching
const concepts = [];
// Simple keyword extraction (in real implementation, this would use NLP/AI)
const keywords = content.toLowerCase().match(/\b\w{4,}\b/g) || [];
const uniqueKeywords = Array.from(new Set(keywords));
for (const keyword of uniqueKeywords.slice(0, 5)) { // Limit to 5 concepts
concepts.push({
id: `concept-${keyword}`,
name: keyword,
confidence: Math.random() * 0.5 + 0.5, // Mock confidence 0.5-1.0
category: 'auto-extracted'
});
}
return concepts;
}
/**
* Find related blocks based on content similarity
*/
export async function findRelatedBlocks(blockId, content, limit = 5) {
// This would integrate with the knowledge system's semantic search
// For now, return mock related block IDs
const mockRelated = [
'block-001', 'block-002', 'block-003', 'block-004', 'block-005'
];
return mockRelated.slice(0, limit);
}
/**
* Create block links between messages and other content
*/
export function createBlockLink(sourceBlockId, targetBlockId, type = 'reference') {
return {
sourceId: sourceBlockId,
targetId: targetBlockId,
type,
context: `Link from ${sourceBlockId} to ${targetBlockId}`
};
}
/**
* Parse block references from content
* Supports [[block-id]] and {{block-id}} syntax
*/
export function parseBlockReferences(content) {
const linkRegex = /\[\[([^\]]+)\]\]/g;
const transclusionRegex = /\{\{([^}]+)\}\}/g;
const links = [];
const transclusions = [];
let match;
// Extract block links [[block-id]]
while ((match = linkRegex.exec(content)) !== null) {
links.push(match[1]);
}
// Extract block transclusions {{block-id}}
while ((match = transclusionRegex.exec(content)) !== null) {
transclusions.push(match[1]);
}
return { links, transclusions };
}
/**
* Generate message suggestions based on context
*/
export async function generateMessageSuggestions(messageHistory, currentUser, context) {
// This would integrate with an AI service for generating contextual suggestions
// For now, return mock suggestions
const suggestions = [
"Can you elaborate on that?",
"That's interesting. How does it relate to...",
"I'd like to learn more about this topic",
"Could you provide an example?",
"What are the implications of this?"
];
return suggestions.slice(0, 3);
}
/**
* Index message content for search
*/
export async function indexMessageContent(message) {
// This would send the message content to the search indexing system
const block = messageToKnowledgeBlock(message);
// Extract concepts and references
const content = typeof message.content === 'string'
? message.content
: message.content.text || '';
const concepts = await extractSemanticConcepts(content);
const references = parseBlockReferences(content);
// In a real implementation, this would:
// 1. Store the block in the knowledge graph
// 2. Index the content for full-text search
// 3. Create semantic embeddings
// 4. Link to related concepts and blocks
// 5. Update backlinks in referenced blocks
console.log('Indexing message:', {
blockId: block.id,
concepts: concepts.map(c => c.name),
links: references.links,
transclusions: references.transclusions
});
}
/**
* Search messages and related content
*/
export async function searchKnowledgeBase(query, messageHistory, options = {}) {
const { includeMessages = true, includeNotes = true, includeConcepts = true, limit = 10 } = options;
// This would integrate with the actual search system
// For now, return mock results based on simple text matching
const results = {
messages: [],
blocks: [],
concepts: []
};
if (includeMessages) {
results.messages = messageHistory.filter(msg => msg.content.toLowerCase().includes(query.toLowerCase())).slice(0, limit);
}
if (includeConcepts) {
// Mock concept search
results.concepts = [
{
id: `concept-${query}`,
name: query,
description: `Concept related to ${query}`,
confidence: 0.8
}
];
}
return results;
}
/**
* Get conversation context for AI agents
*/
export function getConversationContext(messages, maxMessages = 10, includeMetadata = true) {
const recentMessages = messages.slice(-maxMessages);
let context = "Conversation Context:\n\n";
for (const message of recentMessages) {
const content = typeof message.content === 'string'
? message.content
: message.content.text || '';
context += `${message.sender.name} (${message.sender.type}): ${content}\n`;
if (includeMetadata && message.metadata) {
if (message.metadata.semanticTags?.length) {
context += ` Tags: ${message.metadata.semanticTags.join(', ')}\n`;
}
if (message.metadata.blockLinks?.length) {
context += ` Links: ${message.metadata.blockLinks.join(', ')}\n`;
}
}
context += "\n";
}
return context;
}
/**
* Auto-tag messages with semantic concepts
*/
export async function autoTagMessage(content) {
const concepts = await extractSemanticConcepts(content);
return concepts
.filter(c => c.confidence > 0.7) // Only high-confidence concepts
.map(c => c.name);
}
/**
* Suggest block links based on content similarity
*/
export async function suggestBlockLinks(content, existingBlocks) {
// This would use semantic similarity to suggest relevant blocks
// For now, return mock suggestions based on keyword matching
const contentLower = content.toLowerCase();
const suggestions = [];
for (const block of existingBlocks) {
const blockContentLower = block.content.toLowerCase();
const commonWords = contentLower.split(' ').filter(word => word.length > 3 && blockContentLower.includes(word));
if (commonWords.length > 2) { // Arbitrary threshold
suggestions.push(block.id);
}
}
return suggestions.slice(0, 5); // Limit suggestions
}