mirror of
https://github.com/ChatGPTNextWeb/ChatGPT-Next-Web.git
synced 2025-11-14 05:03:43 +08:00
feat: 使用langchain实现插件功能
This commit is contained in:
@@ -18,22 +18,27 @@ import { prettyObject } from "../utils/format";
|
||||
import { estimateTokenLength } from "../utils/token";
|
||||
import { nanoid } from "nanoid";
|
||||
|
||||
export interface ChatToolMessage {
|
||||
toolName: string;
|
||||
toolInput?: string;
|
||||
}
|
||||
|
||||
export type ChatMessage = RequestMessage & {
|
||||
date: string;
|
||||
toolMessages: ChatToolMessage[];
|
||||
streaming?: boolean;
|
||||
isError?: boolean;
|
||||
id: string;
|
||||
model?: ModelType;
|
||||
toolPrompt?: string;
|
||||
};
|
||||
|
||||
export function createMessage(override: Partial<ChatMessage>): ChatMessage {
|
||||
return {
|
||||
id: nanoid(),
|
||||
date: new Date().toLocaleString(),
|
||||
toolMessages: new Array<ChatToolMessage>(),
|
||||
role: "user",
|
||||
content: "",
|
||||
toolPrompt: undefined,
|
||||
...override,
|
||||
};
|
||||
}
|
||||
@@ -56,7 +61,7 @@ export interface ChatSession {
|
||||
clearContextIndex?: number;
|
||||
|
||||
mask: Mask;
|
||||
webSearch: boolean;
|
||||
useTools: boolean;
|
||||
}
|
||||
|
||||
export const DEFAULT_TOPIC = Locale.Store.DefaultTopic;
|
||||
@@ -80,7 +85,7 @@ function createEmptySession(): ChatSession {
|
||||
lastSummarizeIndex: 0,
|
||||
|
||||
mask: createEmptyMask(),
|
||||
webSearch: false,
|
||||
useTools: true,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -308,91 +313,126 @@ export const useChatStore = create<ChatStore>()(
|
||||
content,
|
||||
};
|
||||
session.messages.push(savedUserMessage);
|
||||
});
|
||||
|
||||
if (session.webSearch) {
|
||||
const query = encodeURIComponent(content);
|
||||
let searchResult = await api.searchTool.call(query);
|
||||
console.log("[Tools] ", searchResult);
|
||||
const webSearchPrompt = `
|
||||
Using the provided web search results, write a comprehensive reply to the given query.
|
||||
If the provided search results refer to multiple subjects with the same name, write separate answers for each subject.
|
||||
Make sure to cite results using \`[[number](URL)]\` notation after the reference.
|
||||
|
||||
Web search json results:
|
||||
"""
|
||||
${JSON.stringify(searchResult)}
|
||||
"""
|
||||
|
||||
Current date:
|
||||
"""
|
||||
${new Date().toISOString()}
|
||||
"""
|
||||
|
||||
Query:
|
||||
"""
|
||||
${content}
|
||||
"""
|
||||
|
||||
Reply in ${getLang()} and markdown.`;
|
||||
userMessage.toolPrompt = webSearchPrompt;
|
||||
}
|
||||
// save user's and bot's message
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages.push(botMessage);
|
||||
});
|
||||
|
||||
// make request
|
||||
api.llm.chat({
|
||||
messages: sendMessages,
|
||||
config: { ...modelConfig, stream: true },
|
||||
onUpdate(message) {
|
||||
botMessage.streaming = true;
|
||||
if (message) {
|
||||
botMessage.content = message;
|
||||
}
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
},
|
||||
onFinish(message) {
|
||||
botMessage.streaming = false;
|
||||
if (message) {
|
||||
botMessage.content = message;
|
||||
get().onNewMessage(botMessage);
|
||||
}
|
||||
ChatControllerPool.remove(session.id, botMessage.id);
|
||||
},
|
||||
onError(error) {
|
||||
const isAborted = error.message.includes("aborted");
|
||||
botMessage.content =
|
||||
"\n\n" +
|
||||
prettyObject({
|
||||
error: true,
|
||||
message: error.message,
|
||||
if (session.useTools && modelConfig.model.endsWith("0613")) {
|
||||
console.log("[ToolAgent] start");
|
||||
api.llm.toolAgentChat({
|
||||
messages: sendMessages,
|
||||
config: { ...modelConfig, stream: true },
|
||||
onUpdate(message) {
|
||||
botMessage.streaming = true;
|
||||
if (message) {
|
||||
botMessage.content = message;
|
||||
}
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
botMessage.streaming = false;
|
||||
userMessage.isError = !isAborted;
|
||||
botMessage.isError = !isAborted;
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
ChatControllerPool.remove(
|
||||
session.id,
|
||||
botMessage.id ?? messageIndex,
|
||||
);
|
||||
},
|
||||
onToolUpdate(toolName, toolInput) {
|
||||
botMessage.streaming = true;
|
||||
if (toolName && toolInput) {
|
||||
botMessage.toolMessages.push({
|
||||
toolName,
|
||||
toolInput,
|
||||
});
|
||||
}
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
},
|
||||
onFinish(message) {
|
||||
botMessage.streaming = false;
|
||||
if (message) {
|
||||
botMessage.content = message;
|
||||
get().onNewMessage(botMessage);
|
||||
}
|
||||
ChatControllerPool.remove(session.id, botMessage.id);
|
||||
},
|
||||
onError(error) {
|
||||
const isAborted = error.message.includes("aborted");
|
||||
botMessage.content =
|
||||
"\n\n" +
|
||||
prettyObject({
|
||||
error: true,
|
||||
message: error.message,
|
||||
});
|
||||
botMessage.streaming = false;
|
||||
userMessage.isError = !isAborted;
|
||||
botMessage.isError = !isAborted;
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
ChatControllerPool.remove(
|
||||
session.id,
|
||||
botMessage.id ?? messageIndex,
|
||||
);
|
||||
|
||||
console.error("[Chat] failed ", error);
|
||||
},
|
||||
onController(controller) {
|
||||
// collect controller for stop/retry
|
||||
ChatControllerPool.addController(
|
||||
session.id,
|
||||
botMessage.id ?? messageIndex,
|
||||
controller,
|
||||
);
|
||||
},
|
||||
});
|
||||
console.error("[Chat] failed ", error);
|
||||
},
|
||||
onController(controller) {
|
||||
// collect controller for stop/retry
|
||||
ChatControllerPool.addController(
|
||||
session.id,
|
||||
botMessage.id ?? messageIndex,
|
||||
controller,
|
||||
);
|
||||
},
|
||||
});
|
||||
} else {
|
||||
// make request
|
||||
api.llm.chat({
|
||||
messages: sendMessages,
|
||||
config: { ...modelConfig, stream: true },
|
||||
onUpdate(message) {
|
||||
botMessage.streaming = true;
|
||||
if (message) {
|
||||
botMessage.content = message;
|
||||
}
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
},
|
||||
onFinish(message) {
|
||||
botMessage.streaming = false;
|
||||
if (message) {
|
||||
botMessage.content = message;
|
||||
get().onNewMessage(botMessage);
|
||||
}
|
||||
ChatControllerPool.remove(session.id, botMessage.id);
|
||||
},
|
||||
onError(error) {
|
||||
const isAborted = error.message.includes("aborted");
|
||||
botMessage.content =
|
||||
"\n\n" +
|
||||
prettyObject({
|
||||
error: true,
|
||||
message: error.message,
|
||||
});
|
||||
botMessage.streaming = false;
|
||||
userMessage.isError = !isAborted;
|
||||
botMessage.isError = !isAborted;
|
||||
get().updateCurrentSession((session) => {
|
||||
session.messages = session.messages.concat();
|
||||
});
|
||||
ChatControllerPool.remove(
|
||||
session.id,
|
||||
botMessage.id ?? messageIndex,
|
||||
);
|
||||
|
||||
console.error("[Chat] failed ", error);
|
||||
},
|
||||
onController(controller) {
|
||||
// collect controller for stop/retry
|
||||
ChatControllerPool.addController(
|
||||
session.id,
|
||||
botMessage.id ?? messageIndex,
|
||||
controller,
|
||||
);
|
||||
},
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
getMemoryPrompt() {
|
||||
@@ -532,7 +572,7 @@ Reply in ${getLang()} and markdown.`;
|
||||
api.llm.chat({
|
||||
messages: topicMessages,
|
||||
config: {
|
||||
model: "gpt-3.5-turbo",
|
||||
model: "gpt-3.5-turbo-0613",
|
||||
},
|
||||
onFinish(message) {
|
||||
get().updateCurrentSession(
|
||||
|
||||
Reference in New Issue
Block a user