Add LLM token

This commit is contained in:
wangwei
2026-07-02 22:03:39 +08:00
parent e3afb8a07a
commit 52e67b0e7b
36 changed files with 2392 additions and 394 deletions
+91
View File
@@ -76,6 +76,27 @@ function parseSSEChunk(raw: string, onMessage: (data: SSEMessage) => void) {
onMessage({ type: 'error', text: joined });
} else if (eventName === 'status') {
onMessage({ type: 'status', text: joined });
} else if (eventName === 'thinking') {
// P0-1: Agentic reasoning step events from /agent/agentic/stream
try {
const payload = JSON.parse(joined) as Record<string, unknown>;
onMessage({
type: 'thinking',
step: payload.step as string | undefined,
status: payload.status as string | undefined,
intent_type: payload.intent_type as string | undefined,
requires_decomposition: payload.requires_decomposition as boolean | undefined,
reason: payload.reason as string | undefined,
sub_queries: payload.sub_queries as string[] | undefined,
query: payload.query as string | undefined,
index: payload.index as number | undefined,
total: payload.total as number | undefined,
found: payload.found as number | undefined,
retry: payload.retry as boolean | undefined,
sufficient: payload.sufficient as boolean | undefined,
confidence: payload.confidence as number | undefined,
});
} catch { /* ignore */ }
} else if (eventName === 'message') {
// /rag/chat format: event:message + JSON body with type field
try {
@@ -147,3 +168,73 @@ export async function ragChat(
}
export type { QuickQuestionsResponse, SSEMessage };
/**
* P0-1 Agentic RAG chat — calls /agent/agentic/stream which runs the full
* intent-analysis → query-planning → retrieval → grounding-check → answer pipeline.
*
* The onMessage callback receives the same event types as ragChat plus
* ``type: 'thinking'`` events that carry live reasoning-step progress.
*/
export async function agenticChat(
query: string,
topK: number = 5,
onMessage: (data: SSEMessage) => void,
onError?: (error: Error) => void,
onComplete?: () => void,
filters?: string,
sessionId?: string,
signal?: AbortSignal,
contextText?: string,
contextFilename?: string,
): Promise<void> {
try {
const response = await fetch(`${AGENT_API_BASE}/agent/agentic/stream`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Accept: 'text/event-stream',
...(getToken() ? { Authorization: `Bearer ${getToken()}` } : {}),
},
body: JSON.stringify({
query,
top_k: topK,
...(filters ? { filters } : {}),
...(sessionId ? { session_id: sessionId } : {}),
...(contextText ? { context_text: contextText, context_filename: contextFilename ?? '' } : {}),
}),
signal,
});
if (!response.ok || !response.body) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const parts = buffer.split('\n\n');
buffer = parts.pop() || '';
parseSSEChunk(parts.join('\n\n'), onMessage);
}
if (buffer.trim()) {
parseSSEChunk(buffer, onMessage);
}
if (onComplete) {
onComplete();
}
} catch (error) {
if (error instanceof DOMException && error.name === 'AbortError') return;
if (onError) {
onError(error instanceof Error ? error : new Error(String(error)));
}
}
}