init
This commit is contained in:
Vendored
+81
@@ -0,0 +1,81 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import cors from "cors";
|
||||
import express from "express";
|
||||
import { ChatSessionBridge } from "./chat/sessionBridge.js";
|
||||
import { config } from "./config.js";
|
||||
import { logger } from "./logger.js";
|
||||
import { buildChatRouter } from "./routes/chat.js";
|
||||
import { opencodeRuntime } from "./runtime/opencode.js";
|
||||
import { SessionRegistry } from "./session/registry.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 internalToken = config.AGENT_INTERNAL_TOKEN ?? randomUUID();
|
||||
process.env.TJWATER_AGENT_INTERNAL_TOKEN = internalToken;
|
||||
app.use(cors());
|
||||
app.use(express.json({ limit: "1mb" }));
|
||||
app.get("/health", async (_req, res) => {
|
||||
try {
|
||||
const runtime = await opencodeRuntime.health();
|
||||
res.json({
|
||||
ok: true,
|
||||
runtime,
|
||||
sessions: sessionBridge.count(),
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
res.status(503).json({
|
||||
ok: false,
|
||||
message: "opencode runtime unavailable",
|
||||
detail,
|
||||
sessions: sessionBridge.count(),
|
||||
});
|
||||
}
|
||||
});
|
||||
app.post("/internal/tools/dynamic-http-call", 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 context = sessionBridge.getSessionContext(sessionId);
|
||||
if (!context) {
|
||||
res.status(404).json({
|
||||
message: "session context not found",
|
||||
detail: sessionId,
|
||||
});
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const result = await dynamicHttpExecutor.execute({
|
||||
path: req.body?.path,
|
||||
method: req.body?.method,
|
||||
arguments: req.body?.arguments,
|
||||
}, context);
|
||||
res.json(result);
|
||||
}
|
||||
catch (error) {
|
||||
const detail = error instanceof Error ? error.message : String(error);
|
||||
res.status(400).json({
|
||||
message: "dynamic http execution failed",
|
||||
detail,
|
||||
});
|
||||
}
|
||||
});
|
||||
app.use("/api/v1/copilot/chat", buildChatRouter(sessionBridge, opencodeRuntime));
|
||||
const server = app.listen(config.PORT, config.HOST, () => {
|
||||
logger.info({ host: config.HOST, port: config.PORT }, "TJWaterAgent listening");
|
||||
});
|
||||
const shutdown = async () => {
|
||||
logger.info("shutting down TJWaterAgent");
|
||||
server.close();
|
||||
await opencodeRuntime.dispose();
|
||||
};
|
||||
process.on("SIGINT", () => {
|
||||
void shutdown();
|
||||
});
|
||||
process.on("SIGTERM", () => {
|
||||
void shutdown();
|
||||
});
|
||||
Reference in New Issue
Block a user