feat(agent): add typed server API tools

This commit is contained in:
2026-07-15 10:44:07 +08:00
parent f3f873e3c4
commit 8a21908785
30 changed files with 3119 additions and 15 deletions
+22
View File
@@ -18,6 +18,8 @@ import {
import { buildChatRouter } from "./routes/chat.js";
import { FrontendActionCoordinator, FrontendActionError } from "./frontendAction/coordinator.js";
import { opencodeRuntime } from "./runtime/opencode.js";
import { ServerApiGateway } from "./serverApi/gateway.js";
import { isDomainToolName } from "./serverApi/schemas.js";
import {
getRuntimeSessionContext,
type RuntimeSessionContext,
@@ -38,6 +40,7 @@ const learningOrchestrator = new LearningOrchestrator(
);
const resultReferenceStore = new ResultReferenceStore();
const resultReferenceResolver = new ResultReferenceResolver(resultReferenceStore);
const serverApiGateway = new ServerApiGateway(resultReferenceResolver);
const internalToken = config.AGENT_INTERNAL_TOKEN ?? randomUUID();
const frontendActionCoordinator = new FrontendActionCoordinator();
@@ -47,6 +50,25 @@ process.env.TJWATER_AGENT_INTERNAL_TOKEN = internalToken;
app.use(cors());
app.use(express.json({ limit: "1mb" }));
app.post("/internal/tools/server-api/:tool", async (req, res) => {
if (req.header("x-agent-internal-token") !== internalToken) {
res.status(403).json({ message: "forbidden" });
return;
}
const name = req.params.tool;
if (!isDomainToolName(name)) {
res.status(404).json({ message: "unknown domain tool" });
return;
}
const sessionId = typeof req.body?.session_id === "string" ? req.body.session_id.trim() : "";
const context = sessionId ? getRuntimeSessionContext(sessionId) : null;
if (!context) {
res.status(404).json({ message: "session context not found" });
return;
}
res.json(await serverApiGateway.execute(name, req.body?.args ?? {}, context));
});
app.post("/internal/frontend-actions/request", async (req, res) => {
if (req.header("x-agent-internal-token") !== internalToken) {
res.status(403).json({ message: "forbidden" });