diff options
| author | Adam Malczewski <[email protected]> | 2026-06-28 12:59:07 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-06-28 12:59:07 +0900 |
| commit | 71c635f7d8ee01a2b23d5ddfdfc4bff043980052 (patch) | |
| tree | 1285beba4405e8d0955dcee340a1180aa6ce3a46 /packages/transport-http/src | |
| parent | b83aa8ddbb7023ae9dd0332b4989d4baa11522af (diff) | |
| download | dispatch-71c635f7d8ee01a2b23d5ddfdfc4bff043980052.tar.gz dispatch-71c635f7d8ee01a2b23d5ddfdfc4bff043980052.zip | |
feat(workspace-star): starred workspace priority for concurrency limiting
Diffstat (limited to 'packages/transport-http/src')
| -rw-r--r-- | packages/transport-http/src/app.ts | 53 | ||||
| -rw-r--r-- | packages/transport-http/src/extension.ts | 1 |
2 files changed, 54 insertions, 0 deletions
diff --git a/packages/transport-http/src/app.ts b/packages/transport-http/src/app.ts index 0fcc8f0..0d42e06 100644 --- a/packages/transport-http/src/app.ts +++ b/packages/transport-http/src/app.ts @@ -1489,6 +1489,59 @@ export function createApp(opts: CreateServerOptions): Hono { } }); + // ─── Star/unstar workspace (concurrency priority) ─────────────────────────── + // Starred workspaces receive PRIORITY in the concurrency limiter queue — + // their agents jump ahead of agents from non-starred workspaces. The + // starred state is persisted in the conversation store AND the in-memory + // cache in the concurrency service is notified so already-queued agents + // are re-prioritized immediately. + + app.put("/workspaces/:id/star", async (c) => { + const workspaceId = c.req.param("id"); + if (!isValidWorkspaceSlug(workspaceId)) { + return c.json( + { + error: "Workspace id must be a valid slug (lowercase alphanumeric + hyphens, 1–40 chars)", + }, + 400, + ); + } + try { + const workspace = await opts.conversationStore.setWorkspaceStarred(workspaceId, true); + // Notify the concurrency service's in-memory cache so queued agents + // from this workspace jump ahead immediately. + opts.concurrencyService?.notifyWorkspaceStarred(workspaceId, true); + log.info("workspaces: starred", { workspaceId }); + const response: WorkspaceResponse = workspace; + return c.json(response, 200); + } catch (err) { + log.error("workspaces: star failure", { err, workspaceId }); + return c.json({ error: "Failed to star workspace" }, 500); + } + }); + + app.delete("/workspaces/:id/star", async (c) => { + const workspaceId = c.req.param("id"); + if (!isValidWorkspaceSlug(workspaceId)) { + return c.json( + { + error: "Workspace id must be a valid slug (lowercase alphanumeric + hyphens, 1–40 chars)", + }, + 400, + ); + } + try { + const workspace = await opts.conversationStore.setWorkspaceStarred(workspaceId, false); + opts.concurrencyService?.notifyWorkspaceStarred(workspaceId, false); + log.info("workspaces: unstarred", { workspaceId }); + const response: WorkspaceResponse = workspace; + return c.json(response, 200); + } catch (err) { + log.error("workspaces: unstar failure", { err, workspaceId }); + return c.json({ error: "Failed to unstar workspace" }, 500); + } + }); + // ─── Heartbeat (per-workspace AI loop) ───────────────────────────────────── // The config + run history for a workspace's heartbeat loop. Delegated to // the HeartbeatService (provided by the `heartbeat` extension). When diff --git a/packages/transport-http/src/extension.ts b/packages/transport-http/src/extension.ts index f46fca5..5bf16b3 100644 --- a/packages/transport-http/src/extension.ts +++ b/packages/transport-http/src/extension.ts @@ -72,6 +72,7 @@ export const manifest: Manifest = { "/workspaces/:id/heartbeat", "/workspaces/:id/heartbeat/runs", "/workspaces/:id/heartbeat/runs/:runId/stop", + "/workspaces/:id/star", "/workspaces/:id/title", ], }, |
