/** * Hub entry — skeleton. * * Wires the provider-agnostic agent seam end-to-end with a no-op Feishu read, so * the invariant path is exercised without live credentials. Real wiring (Fastify * server, Feishu OAuth/event callbacks, Prisma, admin-web) lands incrementally; * this file proves the seam compiles and the pieces connect. */ import { OpenRouterProvider } from "./agent/openrouter-provider.js"; import { InMemoryModelRegistry } from "./agent/models.js"; import { ToolRegistry, feishuContextTool } from "./agent/tools.js"; import { runAgent } from "./agent/runner.js"; function main(): void { const apiKey = process.env["OPENROUTER_API_KEY"]; if (apiKey === undefined || apiKey === "") { console.error("[hub] OPENROUTER_API_KEY not set; nothing to run. Exiting."); process.exit(1); } const provider = new OpenRouterProvider({ apiKey }); const models = new InMemoryModelRegistry( [ { id: "z-ai/glm-4.6", label: "GLM-4.6", toolCapable: true }, { id: "anthropic/claude-3.5-sonnet", label: "Claude 3.5 Sonnet", toolCapable: true }, ], { draft: "z-ai/glm-4.6", review: "anthropic/claude-3.5-sonnet" }, ); const tools = new ToolRegistry(); tools.register( feishuContextTool(async (args) => { // Skeleton: no live Feishu calls. Real impl wraps @larksuiteoapi/node-sdk. return JSON.stringify({ stub: true, anchor: args.anchor, id: args.id }); }), ); const model = models.resolve(undefined, "draft"); runAgent(provider, tools, { prompt: "ping", model, role: "draft", project: { projectId: "proj-skeleton", boundChatId: "chat-skeleton", workspaceDir: "/tmp/cph-skeleton", }, }) .then((r) => { console.log("[hub] run finished", { status: r.status, model, usage: r.usage }); if (r.error !== undefined) console.error("[hub] error:", r.error); }) .catch((e) => { console.error("[hub] run threw:", e); process.exit(1); }); } main();