fix: onfinish responseRes

This commit is contained in:
Dogtiti 2024-11-04 17:00:45 +08:00
parent 2d3f7c922f
commit 44fc5b5cbf
15 changed files with 50 additions and 42 deletions

View File

@ -70,7 +70,7 @@ export interface ChatOptions {
config: LLMConfig; config: LLMConfig;
onUpdate?: (message: string, chunk: string) => void; onUpdate?: (message: string, chunk: string) => void;
onFinish: (message: string) => void; onFinish: (message: string, responseRes: Response) => void;
onError?: (err: Error) => void; onError?: (err: Error) => void;
onController?: (controller: AbortController) => void; onController?: (controller: AbortController) => void;
onBeforeTool?: (tool: ChatMessageTool) => void; onBeforeTool?: (tool: ChatMessageTool) => void;

View File

@ -143,6 +143,7 @@ export class QwenApi implements LLMApi {
let responseText = ""; let responseText = "";
let remainText = ""; let remainText = "";
let finished = false; let finished = false;
let responseRes: Response;
// animate response to make it looks smooth // animate response to make it looks smooth
function animateResponseText() { function animateResponseText() {
@ -172,7 +173,7 @@ export class QwenApi implements LLMApi {
const finish = () => { const finish = () => {
if (!finished) { if (!finished) {
finished = true; finished = true;
options.onFinish(responseText + remainText); options.onFinish(responseText + remainText, responseRes);
} }
}; };
@ -188,6 +189,7 @@ export class QwenApi implements LLMApi {
"[Alibaba] request response content type: ", "[Alibaba] request response content type: ",
contentType, contentType,
); );
responseRes = res;
if (contentType?.startsWith("text/plain")) { if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text(); responseText = await res.clone().text();
@ -254,7 +256,7 @@ export class QwenApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -317,13 +317,14 @@ export class ClaudeApi implements LLMApi {
}; };
try { try {
controller.signal.onabort = () => options.onFinish(""); controller.signal.onabort = () =>
options.onFinish("", new Response(null, { status: 400 }));
const res = await fetch(path, payload); const res = await fetch(path, payload);
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} catch (e) { } catch (e) {
console.error("failed to chat", e); console.error("failed to chat", e);
options.onError?.(e as Error); options.onError?.(e as Error);

View File

@ -162,6 +162,7 @@ export class ErnieApi implements LLMApi {
let responseText = ""; let responseText = "";
let remainText = ""; let remainText = "";
let finished = false; let finished = false;
let responseRes: Response;
// animate response to make it looks smooth // animate response to make it looks smooth
function animateResponseText() { function animateResponseText() {
@ -191,7 +192,7 @@ export class ErnieApi implements LLMApi {
const finish = () => { const finish = () => {
if (!finished) { if (!finished) {
finished = true; finished = true;
options.onFinish(responseText + remainText); options.onFinish(responseText + remainText, responseRes);
} }
}; };
@ -204,7 +205,7 @@ export class ErnieApi implements LLMApi {
clearTimeout(requestTimeoutId); clearTimeout(requestTimeoutId);
const contentType = res.headers.get("content-type"); const contentType = res.headers.get("content-type");
console.log("[Baidu] request response content type: ", contentType); console.log("[Baidu] request response content type: ", contentType);
responseRes = res;
if (contentType?.startsWith("text/plain")) { if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text(); responseText = await res.clone().text();
return finish(); return finish();
@ -267,7 +268,7 @@ export class ErnieApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = resJson?.result; const message = resJson?.result;
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -130,6 +130,7 @@ export class DoubaoApi implements LLMApi {
let responseText = ""; let responseText = "";
let remainText = ""; let remainText = "";
let finished = false; let finished = false;
let responseRes: Response;
// animate response to make it looks smooth // animate response to make it looks smooth
function animateResponseText() { function animateResponseText() {
@ -159,7 +160,7 @@ export class DoubaoApi implements LLMApi {
const finish = () => { const finish = () => {
if (!finished) { if (!finished) {
finished = true; finished = true;
options.onFinish(responseText + remainText); options.onFinish(responseText + remainText, responseRes);
} }
}; };
@ -175,7 +176,7 @@ export class DoubaoApi implements LLMApi {
"[ByteDance] request response content type: ", "[ByteDance] request response content type: ",
contentType, contentType,
); );
responseRes = res;
if (contentType?.startsWith("text/plain")) { if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text(); responseText = await res.clone().text();
return finish(); return finish();
@ -241,7 +242,7 @@ export class DoubaoApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -177,7 +177,7 @@ export class ChatGLMApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -274,7 +274,7 @@ export class GeminiProApi implements LLMApi {
); );
} }
const message = apiClient.extractMessage(resJson); const message = apiClient.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -117,6 +117,7 @@ export class SparkApi implements LLMApi {
let responseText = ""; let responseText = "";
let remainText = ""; let remainText = "";
let finished = false; let finished = false;
let responseRes: Response;
// Animate response text to make it look smooth // Animate response text to make it look smooth
function animateResponseText() { function animateResponseText() {
@ -143,7 +144,7 @@ export class SparkApi implements LLMApi {
const finish = () => { const finish = () => {
if (!finished) { if (!finished) {
finished = true; finished = true;
options.onFinish(responseText + remainText); options.onFinish(responseText + remainText, responseRes);
} }
}; };
@ -156,7 +157,7 @@ export class SparkApi implements LLMApi {
clearTimeout(requestTimeoutId); clearTimeout(requestTimeoutId);
const contentType = res.headers.get("content-type"); const contentType = res.headers.get("content-type");
console.log("[Spark] request response content type: ", contentType); console.log("[Spark] request response content type: ", contentType);
responseRes = res;
if (contentType?.startsWith("text/plain")) { if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text(); responseText = await res.clone().text();
return finish(); return finish();
@ -231,7 +232,7 @@ export class SparkApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -180,7 +180,7 @@ export class MoonshotApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -361,7 +361,7 @@ export class ChatGPTApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = await this.extractMessage(resJson); const message = await this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -142,6 +142,7 @@ export class HunyuanApi implements LLMApi {
let responseText = ""; let responseText = "";
let remainText = ""; let remainText = "";
let finished = false; let finished = false;
let responseRes: Response;
// animate response to make it looks smooth // animate response to make it looks smooth
function animateResponseText() { function animateResponseText() {
@ -171,7 +172,7 @@ export class HunyuanApi implements LLMApi {
const finish = () => { const finish = () => {
if (!finished) { if (!finished) {
finished = true; finished = true;
options.onFinish(responseText + remainText); options.onFinish(responseText + remainText, responseRes);
} }
}; };
@ -187,7 +188,7 @@ export class HunyuanApi implements LLMApi {
"[Tencent] request response content type: ", "[Tencent] request response content type: ",
contentType, contentType,
); );
responseRes = res;
if (contentType?.startsWith("text/plain")) { if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text(); responseText = await res.clone().text();
return finish(); return finish();
@ -253,7 +254,7 @@ export class HunyuanApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -173,7 +173,7 @@ export class XAIApi implements LLMApi {
const resJson = await res.json(); const resJson = await res.json();
const message = this.extractMessage(resJson); const message = this.extractMessage(resJson);
options.onFinish(message); options.onFinish(message, res);
} }
} catch (e) { } catch (e) {
console.log("[Request] failed to make a chat request", e); console.log("[Request] failed to make a chat request", e);

View File

@ -649,13 +649,14 @@ export const useChatStore = createPersistStore(
stream: false, stream: false,
providerName, providerName,
}, },
onFinish(message) { onFinish(message, responseRes) {
if (!isValidMessage(message)) return; if (responseRes?.status === 200) {
get().updateCurrentSession( get().updateCurrentSession(
(session) => (session) =>
(session.topic = (session.topic =
message.length > 0 ? trimTopic(message) : DEFAULT_TOPIC), message.length > 0 ? trimTopic(message) : DEFAULT_TOPIC),
); );
}
}, },
}); });
} }
@ -669,7 +670,7 @@ export const useChatStore = createPersistStore(
const historyMsgLength = countMessages(toBeSummarizedMsgs); const historyMsgLength = countMessages(toBeSummarizedMsgs);
if (historyMsgLength > modelConfig?.max_tokens ?? 4000) { if (historyMsgLength > (modelConfig?.max_tokens || 4000)) {
const n = toBeSummarizedMsgs.length; const n = toBeSummarizedMsgs.length;
toBeSummarizedMsgs = toBeSummarizedMsgs.slice( toBeSummarizedMsgs = toBeSummarizedMsgs.slice(
Math.max(0, n - modelConfig.historyMessageCount), Math.max(0, n - modelConfig.historyMessageCount),
@ -715,22 +716,20 @@ export const useChatStore = createPersistStore(
onUpdate(message) { onUpdate(message) {
session.memoryPrompt = message; session.memoryPrompt = message;
}, },
onFinish(message) { onFinish(message, responseRes) {
console.log("[Memory] ", message); if (responseRes?.status === 200) {
get().updateCurrentSession((session) => { console.log("[Memory] ", message);
session.lastSummarizeIndex = lastSummarizeIndex; get().updateCurrentSession((session) => {
session.memoryPrompt = message; // Update the memory prompt for stored it in local storage session.lastSummarizeIndex = lastSummarizeIndex;
}); session.memoryPrompt = message; // Update the memory prompt for stored it in local storage
});
}
}, },
onError(err) { onError(err) {
console.error("[Summarize] ", err); console.error("[Summarize] ", err);
}, },
}); });
} }
function isValidMessage(message: any): boolean {
return typeof message === "string" && !message.startsWith("```json");
}
}, },
updateStat(message: ChatMessage) { updateStat(message: ChatMessage) {

View File

@ -174,6 +174,7 @@ export function stream(
let finished = false; let finished = false;
let running = false; let running = false;
let runTools: any[] = []; let runTools: any[] = [];
let responseRes: Response;
// animate response to make it looks smooth // animate response to make it looks smooth
function animateResponseText() { function animateResponseText() {
@ -272,7 +273,7 @@ export function stream(
} }
console.debug("[ChatAPI] end"); console.debug("[ChatAPI] end");
finished = true; finished = true;
options.onFinish(responseText + remainText); options.onFinish(responseText + remainText, responseRes); // 将res传递给onFinish
} }
}; };
@ -304,6 +305,7 @@ export function stream(
clearTimeout(requestTimeoutId); clearTimeout(requestTimeoutId);
const contentType = res.headers.get("content-type"); const contentType = res.headers.get("content-type");
console.log("[Request] response content type: ", contentType); console.log("[Request] response content type: ", contentType);
responseRes = res;
if (contentType?.startsWith("text/plain")) { if (contentType?.startsWith("text/plain")) {
responseText = await res.clone().text(); responseText = await res.clone().text();

View File

@ -19,7 +19,7 @@ type StreamResponse = {
headers: Record<string, string>; headers: Record<string, string>;
}; };
export function fetch(url: string, options?: RequestInit): Promise<any> { export function fetch(url: string, options?: RequestInit): Promise<Response> {
if (window.__TAURI__) { if (window.__TAURI__) {
const { const {
signal, signal,