diff options
| author | Adam Malczewski <[email protected]> | 2026-05-19 19:40:21 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-19 19:40:21 +0900 |
| commit | f78a91c20f658dd404277919a0b872b352c99bb6 (patch) | |
| tree | 58cfffb655da4443f4b7a39543b86f988f15239f /packages/api/src/app.ts | |
| download | dispatch-main.tar.gz dispatch-main.zip | |
- Bun monorepo with @dispatch/core, @dispatch/api, @dispatch/frontend
- Agent runtime with Vercel AI SDK, streaming via WebSocket
- Tools: read_file, write_file, list_files (scoped to working directory)
- Hono API server with POST /chat, GET /status, GET /health, WS /ws
- Svelte 5 + DaisyUI frontend with chat UI, theme switcher, copy button
- OpenCode Go (Zen) as LLM provider, deepseek-v4-flash-free model
- Docker setup (dev + prod) with bin/ scripts and gopass secrets
- Biome v2 linting/formatting, Vitest tests (44 passing)
- Debug info attached to error messages for diagnostics
Diffstat (limited to 'packages/api/src/app.ts')
| -rw-r--r-- | packages/api/src/app.ts | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/packages/api/src/app.ts b/packages/api/src/app.ts new file mode 100644 index 0000000..9c31eab --- /dev/null +++ b/packages/api/src/app.ts @@ -0,0 +1,46 @@ +import { Hono } from "hono"; +import { cors } from "hono/cors"; +import { AgentManager } from "./agent-manager.js"; + +export const agentManager = new AgentManager(); + +export const app = new Hono(); + +app.use( + "*", + cors({ + origin: "http://localhost:5173", + credentials: true, + allowHeaders: ["Content-Type", "Authorization"], + allowMethods: ["GET", "POST", "OPTIONS"], + }), +); + +app.get("/health", (c) => { + return c.json({ ok: true }); +}); + +app.get("/status", (c) => { + return c.json({ + status: agentManager.getStatus(), + messageCount: agentManager.getMessageCount(), + }); +}); + +app.post("/chat", async (c) => { + const body = await c.req.json<{ message?: unknown }>(); + const message = body.message; + + if (typeof message !== "string" || message.trim() === "") { + return c.json({ error: "message must be a non-empty string" }, 400); + } + + if (agentManager.getStatus() === "running") { + return c.json({ error: "agent is already running" }, 409); + } + + // Non-blocking — let the agent run in the background + agentManager.processMessage(message).catch(console.error); + + return c.json({ status: "ok" }); +}); |
