feat: implement RAG-enabled chat hook and admin file upload component
This commit is contained in:
@@ -36,9 +36,16 @@ const UploadZone = ({ onUploadComplete }) => {
|
||||
})
|
||||
.catch((err) => {
|
||||
const isCancelled = err?.name === 'AbortError';
|
||||
let errorMsg = err?.message || 'Unknown error';
|
||||
if (err?.name === 'LLMTruncatedError') {
|
||||
errorMsg = 'File is too large for the AI context window. Please split into smaller chunks.';
|
||||
} else if (err?.name === 'LLMValidationError') {
|
||||
errorMsg = 'AI output was malformed (not JSON). Please try again.';
|
||||
}
|
||||
|
||||
setQueue((q) => q.map((item) =>
|
||||
item.id === next.id
|
||||
? { ...item, status: isCancelled ? 'cancelled' : 'failed', error: isCancelled ? null : err.message }
|
||||
? { ...item, status: isCancelled ? 'cancelled' : 'failed', error: isCancelled ? null : errorMsg }
|
||||
: item
|
||||
));
|
||||
})
|
||||
|
||||
@@ -193,13 +193,24 @@ export function useChat({ user, isAdmin }) {
|
||||
} catch (e) {
|
||||
console.error('[R42] chat error', e);
|
||||
setErrored(true);
|
||||
const isKey = /api key/i.test(e?.message || '');
|
||||
|
||||
let errorContent = STRINGS.errorGeneric;
|
||||
const errorMsg = e?.message || '';
|
||||
|
||||
if (e?.name === 'LLMTruncatedError') {
|
||||
errorContent = 'Mijn circuits zijn overbelast (Token Limiet bereikt). Kun je je vraag korter of specifieker maken?';
|
||||
} else if (e?.name === 'LLMValidationError') {
|
||||
errorContent = 'Mijn antwoord was helaas beschadigd of incorrect geformatteerd. Kun je het nog eens proberen?';
|
||||
} else if (/api key/i.test(errorMsg)) {
|
||||
errorContent = STRINGS.errorNoKey;
|
||||
}
|
||||
|
||||
setMessages(prev => [
|
||||
...prev,
|
||||
{
|
||||
id: `m_${Date.now()}_e`,
|
||||
role: 'error',
|
||||
content: isKey ? STRINGS.errorNoKey : STRINGS.errorGeneric,
|
||||
content: errorContent,
|
||||
ts: Date.now(),
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/**
|
||||
* Back-compatibility shim for the legacy `anthropicApi` interface.
|
||||
*
|
||||
* All real work lives in `./llm.js`. Existing callers (extractionPipeline,
|
||||
* learningService, testService, KnowledgeGraph, useChat) keep working
|
||||
* unchanged; new code should import `callLLM` from `./llm.js` directly.
|
||||
*/
|
||||
|
||||
import { callLLM } from './llm';
|
||||
|
||||
export const anthropicApi = {
|
||||
async generateContent(systemPrompt, userMessage /*, maxRetries */) {
|
||||
const { text } = await callLLM({
|
||||
task: 'legacy.generateContent',
|
||||
tier: 'standard',
|
||||
system: systemPrompt,
|
||||
user: userMessage,
|
||||
maxTokens: 8192,
|
||||
temperature: 0,
|
||||
});
|
||||
return text;
|
||||
},
|
||||
|
||||
async chat(systemPrompt, messages, opts = {}) {
|
||||
const r = await callLLM({
|
||||
task: 'legacy.chat',
|
||||
tier: 'standard',
|
||||
system: systemPrompt,
|
||||
messages,
|
||||
tools: opts.tools,
|
||||
maxTokens: 1024,
|
||||
temperature: 0.3,
|
||||
});
|
||||
const content = [];
|
||||
if (r.text) content.push({ type: 'text', text: r.text });
|
||||
for (const tu of r.toolUses) content.push({ type: 'tool_use', name: tu.name, input: tu.input });
|
||||
return { content, stop_reason: r.stopReason };
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user