feat: 使用langchain实现插件功能

This commit is contained in:
Hk-Gosuto
2023-07-22 15:38:44 +08:00
parent 9223f95726
commit 2bb421b8bf
12 changed files with 906 additions and 128 deletions

View File

@@ -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(