summaryrefslogtreecommitdiffhomepage
path: root/packages/api/src/app.ts
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-05-22 20:54:19 +0900
committerAdam Malczewski <[email protected]>2026-05-22 20:54:19 +0900
commitc47346cc6237044ecb60ff22c4011d89744af581 (patch)
tree2359a25e687e1290ba5180fd60eae83b03b53a23 /packages/api/src/app.ts
parent288b21cec98421fda57028a0c8c9d835cfbb14b0 (diff)
downloaddispatch-c47346cc6237044ecb60ff22c4011d89744af581.tar.gz
dispatch-c47346cc6237044ecb60ff22c4011d89744af581.zip
feat: message queue/interrupt system, CORS fix, mobile fixes, chat splitting
- Add message queue allowing users to send messages while agent is running - Queue messages are injected into tool results as [USER INTERRUPT] - Retrieve tool interrupted via Promise.race when user message arrives - Queued messages show with 'queued' badge and cancel button - Consumed messages repositioned and chat splits at interrupt point - New assistant message block created after interrupt for clean flow - Add POST /chat/cancel endpoint for cancelling queued messages - Fix CORS to allow any origin (Tailscale/LAN access) - Fix crypto.randomUUID fallback for non-secure contexts (HTTP) - Fix frontend API URL derivation from page hostname - Auto-create DB tab if missing on processMessage (foreign key fix) - Add error logging to processMessage catch block - Fix working directory input sync on agent switch - Fix agent mode button to re-apply agent settings
Diffstat (limited to 'packages/api/src/app.ts')
-rw-r--r--packages/api/src/app.ts19
1 files changed, 17 insertions, 2 deletions
diff --git a/packages/api/src/app.ts b/packages/api/src/app.ts
index 37514c3..53cfb6c 100644
--- a/packages/api/src/app.ts
+++ b/packages/api/src/app.ts
@@ -16,7 +16,7 @@ export const app = new Hono();
app.use(
"*",
cors({
- origin: "http://localhost:5173",
+ origin: (origin) => origin || "*",
credentials: true,
allowHeaders: ["Content-Type", "Authorization"],
allowMethods: ["GET", "POST", "PATCH", "PUT", "DELETE", "OPTIONS"],
@@ -43,6 +43,7 @@ app.post("/chat", async (c) => {
modelId?: unknown;
reasoningEffort?: unknown;
workingDirectory?: unknown;
+ queueId?: unknown;
}>();
const { tabId, message } = body;
@@ -55,7 +56,9 @@ app.post("/chat", async (c) => {
}
if (agentManager.getTabStatus(tabId) === "running") {
- return c.json({ error: "agent is already running for this tab" }, 409);
+ const queueId = typeof body.queueId === "string" ? body.queueId : undefined;
+ const { messageId } = agentManager.queueMessage(tabId, message, queueId);
+ return c.json({ status: "queued", messageId });
}
const keyId = typeof body.keyId === "string" ? body.keyId : undefined;
@@ -74,6 +77,18 @@ app.post("/chat", async (c) => {
});
app.route("/config", configRoutes);
+
+app.post("/chat/cancel", async (c) => {
+ const body = await c.req.json();
+ if (typeof body.tabId !== "string" || typeof body.messageId !== "string") {
+ return c.json({ error: "tabId and messageId are required strings" }, 400);
+ }
+ const tabId = body.tabId;
+ const messageId = body.messageId;
+ const cancelled = agentManager.cancelQueuedMessage(tabId, messageId);
+ return c.json({ success: cancelled });
+});
+
app.route("/skills", skillsRoutes);
app.route("/models", modelsRoutes);
app.route("/tabs", tabsRoutes);