LLM-driven 设计,添加学习审计和会话历史存储至目录的功能

This commit is contained in:
2026-05-15 11:50:20 +08:00
parent 2ba4f35a2d
commit 4ec6cbed16
15 changed files with 1557 additions and 133 deletions
+52 -2
View File
@@ -2,20 +2,30 @@ import { randomUUID } from "node:crypto";
import cors from "cors";
import express from "express";
import { SessionHistoryStore } from "./history/store.js";
import { ChatSessionBridge } from "./chat/sessionBridge.js";
import { config } from "./config.js";
import { logger } from "./logger.js";
import { LearningOrchestrator } from "./learning/orchestrator.js";
import { MemoryStore } from "./memory/store.js";
import { ResultReferenceStore } from "./results/store.js";
import { buildChatRouter } from "./routes/chat.js";
import { opencodeRuntime } from "./runtime/opencode.js";
import { SessionRegistry } from "./session/registry.js";
import { ToolSessionContextStore } from "./session/toolContextStore.js";
import { DynamicHttpExecutor } from "./tools/dynamicHttpExecutor.js";
const app = express();
const registry = new SessionRegistry(config.SESSION_TTL_SECONDS);
const sessionBridge = new ChatSessionBridge(registry, opencodeRuntime);
const memoryStore = new MemoryStore();
const sessionHistoryStore = new SessionHistoryStore();
const toolContextStore = new ToolSessionContextStore();
const learningOrchestrator = new LearningOrchestrator(
opencodeRuntime,
memoryStore,
sessionHistoryStore,
);
const resultReferenceStore = new ResultReferenceStore();
const dynamicHttpExecutor = new DynamicHttpExecutor(resultReferenceStore);
const internalToken = config.AGENT_INTERNAL_TOKEN ?? randomUUID();
@@ -126,13 +136,53 @@ app.post("/internal/tools/fetch-result-ref", async (req, res) => {
res.json(result);
});
app.post("/internal/tools/session-search", async (req, res) => {
if (req.header("x-agent-internal-token") !== internalToken) {
res.status(403).json({ message: "forbidden" });
return;
}
const sessionId = typeof req.body?.sessionId === "string" ? req.body.sessionId : "";
const query = typeof req.body?.query === "string" ? req.body.query : "";
const context = await toolContextStore.read(sessionId);
if (!context) {
res.status(404).json({
message: "tool session context not found",
detail: sessionId,
});
return;
}
if (!query.trim()) {
res.status(400).json({ message: "query is required" });
return;
}
const hits = await sessionHistoryStore.search(
{
actorKey: context.actorKey,
projectKey: context.projectKey,
},
query,
typeof req.body?.max_results === "number" ? req.body.max_results : undefined,
);
res.json({
hits,
query,
});
});
app.use(
"/api/v1/agent/chat",
buildChatRouter(sessionBridge, opencodeRuntime, memoryStore),
buildChatRouter(sessionBridge, opencodeRuntime, memoryStore, learningOrchestrator),
);
const bootstrap = async () => {
await Promise.all([memoryStore.initialize(), resultReferenceStore.initialize()]);
await Promise.all([
learningOrchestrator.initialize(),
memoryStore.initialize(),
resultReferenceStore.initialize(),
sessionHistoryStore.initialize(),
toolContextStore.initialize(),
]);
resultReferenceStore.startCleanupLoop();
};