Merge pull request #5759 from ConnectAI-E/feature/onfinish
Feature/onfinish
This commit is contained in:
commit
5733e3c588
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -266,7 +266,9 @@ export function isVisionModel(model: string) {
|
||||||
model.includes("gpt-4-turbo") && !model.includes("preview");
|
model.includes("gpt-4-turbo") && !model.includes("preview");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
visionKeywords.some((keyword) => model.includes(keyword)) || isGpt4Turbo
|
visionKeywords.some((keyword) => model.includes(keyword)) ||
|
||||||
|
isGpt4Turbo ||
|
||||||
|
isDalle3(model)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue