修正记忆重复问题
This commit is contained in:
parent
8e10813dc8
commit
de362e0312
@ -23,7 +23,7 @@ function buildMemPrompt(mem: Awaited<ReturnType<Memory["get"]>>): string {
|
|||||||
|
|
||||||
export default router.get("/", async (req, res) => {
|
export default router.get("/", async (req, res) => {
|
||||||
|
|
||||||
const isolationKey = "test";
|
const isolationKey = "1:productionAgent:1";
|
||||||
const input = "你好"
|
const input = "你好"
|
||||||
|
|
||||||
const memory = new Memory("productionAgent", isolationKey);
|
const memory = new Memory("productionAgent", isolationKey);
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import u from "@/utils";
|
|||||||
import { Namespace, Socket } from "socket.io";
|
import { Namespace, Socket } from "socket.io";
|
||||||
import * as agent from "@/agents/productionAgent/index";
|
import * as agent from "@/agents/productionAgent/index";
|
||||||
import ResTool from "@/socket/resTool";
|
import ResTool from "@/socket/resTool";
|
||||||
import Memory from "@/utils/agent/memory";
|
|
||||||
|
|
||||||
async function verifyToken(rawToken: string): Promise<Boolean> {
|
async function verifyToken(rawToken: string): Promise<Boolean> {
|
||||||
const setting = await u.db("o_setting").where("key", "tokenKey").select("value").first();
|
const setting = await u.db("o_setting").where("key", "tokenKey").select("value").first();
|
||||||
@ -57,7 +56,6 @@ export default (nsp: Namespace) => {
|
|||||||
abortController?.abort();
|
abortController?.abort();
|
||||||
abortController = new AbortController();
|
abortController = new AbortController();
|
||||||
const currentController = abortController;
|
const currentController = abortController;
|
||||||
const memory = new Memory("scriptAgent", isolationKey);
|
|
||||||
|
|
||||||
const msg = resTool.newMessage("assistant", "视频策划");
|
const msg = resTool.newMessage("assistant", "视频策划");
|
||||||
const ctx: agent.AgentContext = {
|
const ctx: agent.AgentContext = {
|
||||||
@ -70,26 +68,16 @@ export default (nsp: Namespace) => {
|
|||||||
msg,
|
msg,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
const textStream = await agent.decisionAI(ctx);
|
const textStream = await agent.decisionAI(ctx);
|
||||||
|
|
||||||
let currentMsg = ctx.msg;
|
let currentMsg = ctx.msg;
|
||||||
let text = currentMsg.text();
|
let text = currentMsg.text();
|
||||||
let currentContent = "";
|
|
||||||
|
|
||||||
const persistCurrentMessage = async () => {
|
const syncCurrentMessage = () => {
|
||||||
if (!currentContent.trim()) return;
|
|
||||||
await memory.add("assistant:decision", currentContent, {
|
|
||||||
name: "视频策划",
|
|
||||||
createTime: new Date(currentMsg.datetime).getTime(),
|
|
||||||
});
|
|
||||||
currentContent = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
const syncCurrentMessage = async () => {
|
|
||||||
if (ctx.msg === currentMsg) return;
|
if (ctx.msg === currentMsg) return;
|
||||||
text.complete();
|
text.complete();
|
||||||
currentMsg.complete();
|
currentMsg.complete();
|
||||||
await persistCurrentMessage();
|
|
||||||
currentMsg = ctx.msg;
|
currentMsg = ctx.msg;
|
||||||
text = currentMsg.text();
|
text = currentMsg.text();
|
||||||
};
|
};
|
||||||
@ -97,9 +85,8 @@ export default (nsp: Namespace) => {
|
|||||||
let aborted = false;
|
let aborted = false;
|
||||||
try {
|
try {
|
||||||
for await (const chunk of textStream) {
|
for await (const chunk of textStream) {
|
||||||
await syncCurrentMessage();
|
syncCurrentMessage();
|
||||||
text.append(chunk);
|
text.append(chunk);
|
||||||
currentContent += chunk;
|
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.name === "AbortError" || currentController.signal.aborted) {
|
if (err.name === "AbortError" || currentController.signal.aborted) {
|
||||||
@ -108,7 +95,7 @@ export default (nsp: Namespace) => {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await syncCurrentMessage();
|
syncCurrentMessage();
|
||||||
if (aborted) {
|
if (aborted) {
|
||||||
text.append("[已停止]");
|
text.append("[已停止]");
|
||||||
text.complete();
|
text.complete();
|
||||||
@ -117,7 +104,15 @@ export default (nsp: Namespace) => {
|
|||||||
text.complete();
|
text.complete();
|
||||||
currentMsg.complete();
|
currentMsg.complete();
|
||||||
}
|
}
|
||||||
await persistCurrentMessage();
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
if (err.name !== "AbortError" && !currentController.signal.aborted) {
|
||||||
|
const errorMsg = u.error(err).message;
|
||||||
|
console.error("[productionAgent] chat error:", errorMsg);
|
||||||
|
ctx.msg.text(errorMsg).complete();
|
||||||
|
ctx.msg.error();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
if (abortController === currentController) {
|
if (abortController === currentController) {
|
||||||
abortController = null;
|
abortController = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,6 @@ import u from "@/utils";
|
|||||||
import { Namespace, Socket } from "socket.io";
|
import { Namespace, Socket } from "socket.io";
|
||||||
import * as agent from "@/agents/scriptAgent/index";
|
import * as agent from "@/agents/scriptAgent/index";
|
||||||
import ResTool from "@/socket/resTool";
|
import ResTool from "@/socket/resTool";
|
||||||
import Memory from "@/utils/agent/memory";
|
|
||||||
|
|
||||||
async function verifyToken(rawToken: string): Promise<Boolean> {
|
async function verifyToken(rawToken: string): Promise<Boolean> {
|
||||||
const setting = await u.db("o_setting").where("key", "tokenKey").select("value").first();
|
const setting = await u.db("o_setting").where("key", "tokenKey").select("value").first();
|
||||||
@ -46,7 +45,6 @@ export default (nsp: Namespace) => {
|
|||||||
abortController?.abort();
|
abortController?.abort();
|
||||||
abortController = new AbortController();
|
abortController = new AbortController();
|
||||||
const currentController = abortController;
|
const currentController = abortController;
|
||||||
const memory = new Memory("scriptAgent", isolationKey);
|
|
||||||
|
|
||||||
const msg = resTool.newMessage("assistant", "统筹");
|
const msg = resTool.newMessage("assistant", "统筹");
|
||||||
const ctx: agent.AgentContext = {
|
const ctx: agent.AgentContext = {
|
||||||
@ -59,26 +57,16 @@ export default (nsp: Namespace) => {
|
|||||||
msg,
|
msg,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
const textStream = await agent.decisionAI(ctx);
|
const textStream = await agent.decisionAI(ctx);
|
||||||
|
|
||||||
let currentMsg = ctx.msg;
|
let currentMsg = ctx.msg;
|
||||||
let text = currentMsg.text();
|
let text = currentMsg.text();
|
||||||
let currentContent = "";
|
|
||||||
|
|
||||||
const persistCurrentMessage = async () => {
|
const syncCurrentMessage = () => {
|
||||||
if (!currentContent.trim()) return;
|
|
||||||
await memory.add("assistant:decision", currentContent, {
|
|
||||||
name: "统筹",
|
|
||||||
createTime: new Date(currentMsg.datetime).getTime(),
|
|
||||||
});
|
|
||||||
currentContent = "";
|
|
||||||
};
|
|
||||||
|
|
||||||
const syncCurrentMessage = async () => {
|
|
||||||
if (ctx.msg === currentMsg) return;
|
if (ctx.msg === currentMsg) return;
|
||||||
text.complete();
|
text.complete();
|
||||||
currentMsg.complete();
|
currentMsg.complete();
|
||||||
await persistCurrentMessage();
|
|
||||||
currentMsg = ctx.msg;
|
currentMsg = ctx.msg;
|
||||||
text = currentMsg.text();
|
text = currentMsg.text();
|
||||||
};
|
};
|
||||||
@ -86,9 +74,8 @@ export default (nsp: Namespace) => {
|
|||||||
let aborted = false;
|
let aborted = false;
|
||||||
try {
|
try {
|
||||||
for await (const chunk of textStream) {
|
for await (const chunk of textStream) {
|
||||||
await syncCurrentMessage();
|
syncCurrentMessage();
|
||||||
text.append(chunk);
|
text.append(chunk);
|
||||||
currentContent += chunk;
|
|
||||||
}
|
}
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
if (err.name === "AbortError" || currentController.signal.aborted) {
|
if (err.name === "AbortError" || currentController.signal.aborted) {
|
||||||
@ -97,7 +84,7 @@ export default (nsp: Namespace) => {
|
|||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
await syncCurrentMessage();
|
syncCurrentMessage();
|
||||||
if (aborted) {
|
if (aborted) {
|
||||||
text.complete();
|
text.complete();
|
||||||
currentMsg.stop();
|
currentMsg.stop();
|
||||||
@ -105,7 +92,15 @@ export default (nsp: Namespace) => {
|
|||||||
text.complete();
|
text.complete();
|
||||||
currentMsg.complete();
|
currentMsg.complete();
|
||||||
}
|
}
|
||||||
await persistCurrentMessage();
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
if (err.name !== "AbortError" && !currentController.signal.aborted) {
|
||||||
|
const errorMsg = u.error(err).message;
|
||||||
|
console.error("[scriptAgent] chat error:", errorMsg);
|
||||||
|
ctx.msg.text(errorMsg).complete();
|
||||||
|
ctx.msg.error();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
if (abortController === currentController) {
|
if (abortController === currentController) {
|
||||||
abortController = null;
|
abortController = null;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,12 @@ async function getVendorTemplateFn(fnName: FnName, modelName: `${string}:${strin
|
|||||||
const selectedModel = modelList.find((i: any) => i.modelName == name);
|
const selectedModel = modelList.find((i: any) => i.modelName == name);
|
||||||
if (!selectedModel) throw new Error(`未找到模型 ${name} id=${id}`);
|
if (!selectedModel) throw new Error(`未找到模型 ${name} id=${id}`);
|
||||||
const jsCode = transform(vendorConfigData.code!, { transforms: ["typescript"] }).code;
|
const jsCode = transform(vendorConfigData.code!, { transforms: ["typescript"] }).code;
|
||||||
const fn = u.vm(jsCode)[fnName];
|
const running = u.vm(jsCode);
|
||||||
|
if (running.vendor) {
|
||||||
|
Object.assign(running.vendor.inputValues, JSON.parse(vendorConfigData.inputValues ?? "{}"));
|
||||||
|
running.vendor.models = modelList;
|
||||||
|
}
|
||||||
|
const fn = running[fnName];
|
||||||
if (!fn) throw new Error(`未找到供应商配置中的函数 ${fnName} id=${id}`);
|
if (!fn) throw new Error(`未找到供应商配置中的函数 ${fnName} id=${id}`);
|
||||||
if (fnName == "textRequest") return fn(selectedModel);
|
if (fnName == "textRequest") return fn(selectedModel);
|
||||||
else return <T>(input: T) => fn(input, selectedModel);
|
else return <T>(input: T) => fn(input, selectedModel);
|
||||||
@ -115,13 +120,18 @@ class AiImage {
|
|||||||
constructor(key: `${string}:${string}`) {
|
constructor(key: `${string}:${string}`) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
async run(input: ImageConfig, taskRecord: TaskRecord) {
|
async run(input: ImageConfig, taskRecord?: TaskRecord) {
|
||||||
return withTaskRecord(this.key, taskRecord.taskClass, taskRecord.describe, taskRecord.relatedObjects, taskRecord.projectId, async (modelName) => {
|
const modelName = await resolveModelName(this.key);
|
||||||
const fn = await getVendorTemplateFn("imageRequest", modelName);
|
const exec = async (mn: `${string}:${string}`) => {
|
||||||
|
const fn = await getVendorTemplateFn("imageRequest", mn);
|
||||||
this.result = await fn(input);
|
this.result = await fn(input);
|
||||||
if (this.result.startsWith("http")) this.result = await urlToBase64(this.result);
|
if (this.result.startsWith("http")) this.result = await urlToBase64(this.result);
|
||||||
return this;
|
return this;
|
||||||
});
|
};
|
||||||
|
if (taskRecord) {
|
||||||
|
return withTaskRecord(this.key, taskRecord.taskClass, taskRecord.describe, taskRecord.relatedObjects, taskRecord.projectId, exec);
|
||||||
|
}
|
||||||
|
return exec(modelName);
|
||||||
}
|
}
|
||||||
async save(path: string) {
|
async save(path: string) {
|
||||||
await u.oss.writeFile(path, this.result);
|
await u.oss.writeFile(path, this.result);
|
||||||
@ -144,13 +154,18 @@ class AiVideo {
|
|||||||
constructor(key: `${string}:${string}`) {
|
constructor(key: `${string}:${string}`) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
async run(input: VideoConfig, taskRecord: TaskRecord) {
|
async run(input: VideoConfig, taskRecord?: TaskRecord) {
|
||||||
return withTaskRecord(this.key, taskRecord.taskClass, taskRecord.describe, taskRecord.relatedObjects, taskRecord.projectId, async (modelName) => {
|
const modelName = await resolveModelName(this.key);
|
||||||
const fn = await getVendorTemplateFn("videoRequest", modelName);
|
const exec = async (mn: `${string}:${string}`) => {
|
||||||
|
const fn = await getVendorTemplateFn("videoRequest", mn);
|
||||||
this.result = await fn(input);
|
this.result = await fn(input);
|
||||||
if (this.result.startsWith("http")) this.result = await urlToBase64(this.result);
|
if (this.result.startsWith("http")) this.result = await urlToBase64(this.result);
|
||||||
return this;
|
return this;
|
||||||
});
|
};
|
||||||
|
if (taskRecord) {
|
||||||
|
return withTaskRecord(this.key, taskRecord.taskClass, taskRecord.describe, taskRecord.relatedObjects, taskRecord.projectId, exec);
|
||||||
|
}
|
||||||
|
return exec(modelName);
|
||||||
}
|
}
|
||||||
async save(path: string) {
|
async save(path: string) {
|
||||||
await u.oss.writeFile(path, this.result);
|
await u.oss.writeFile(path, this.result);
|
||||||
@ -163,13 +178,18 @@ class AiAudio {
|
|||||||
constructor(key: `${string}:${string}`) {
|
constructor(key: `${string}:${string}`) {
|
||||||
this.key = key;
|
this.key = key;
|
||||||
}
|
}
|
||||||
async run(input: VideoConfig, taskRecord: TaskRecord) {
|
async run(input: VideoConfig, taskRecord?: TaskRecord) {
|
||||||
return withTaskRecord(this.key, taskRecord.taskClass, taskRecord.describe, taskRecord.relatedObjects, taskRecord.projectId, async (modelName) => {
|
const modelName = await resolveModelName(this.key);
|
||||||
const fn = await getVendorTemplateFn("ttsRequest", modelName);
|
const exec = async (mn: `${string}:${string}`) => {
|
||||||
|
const fn = await getVendorTemplateFn("ttsRequest", mn);
|
||||||
this.result = await fn(input);
|
this.result = await fn(input);
|
||||||
if (this.result.startsWith("http")) this.result = await urlToBase64(this.result);
|
if (this.result.startsWith("http")) this.result = await urlToBase64(this.result);
|
||||||
return this;
|
return this;
|
||||||
});
|
};
|
||||||
|
if (taskRecord) {
|
||||||
|
return withTaskRecord(this.key, taskRecord.taskClass, taskRecord.describe, taskRecord.relatedObjects, taskRecord.projectId, exec);
|
||||||
|
}
|
||||||
|
return exec(modelName);
|
||||||
}
|
}
|
||||||
async save(path: string) {
|
async save(path: string) {
|
||||||
await u.oss.writeFile(path, this.result);
|
await u.oss.writeFile(path, this.result);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user