summaryrefslogtreecommitdiffhomepage
path: root/packages/api
diff options
context:
space:
mode:
authorAdam Malczewski <[email protected]>2026-05-20 23:37:01 +0900
committerAdam Malczewski <[email protected]>2026-05-20 23:37:01 +0900
commit1f4776e6891348d2dbdcbbf704c0a5901b008ecf (patch)
treed406c2ba412b5393b16a3f9253acea34807d0dda /packages/api
parent29e4c2db4555bb764f458971f0c591c092e30ed6 (diff)
downloaddispatch-1f4776e6891348d2dbdcbbf704c0a5901b008ecf.tar.gz
dispatch-1f4776e6891348d2dbdcbbf704c0a5901b008ecf.zip
feat: Claude Reset scheduler + fix key config and Claude grouping
- Added claude-pro key pointing to default credentials, claude-max pointing to .credentials-2.json (docker path /root/.claude/) - POST /models/wake sends 'hi' to haiku for all Claude accounts - ClaudeReset.svelte: 2 AM rows + 2 PM rows of 6 hour blocks each (12-hour American format). Click blocks to schedule wake at :15 - Key Usage now groups all Claude accounts under one 'Claude' card instead of duplicating under claude-pro and claude-max cards
Diffstat (limited to 'packages/api')
-rw-r--r--packages/api/src/routes/models.ts45
1 files changed, 45 insertions, 0 deletions
diff --git a/packages/api/src/routes/models.ts b/packages/api/src/routes/models.ts
index 906ecc4..79f25cc 100644
--- a/packages/api/src/routes/models.ts
+++ b/packages/api/src/routes/models.ts
@@ -7,6 +7,8 @@ import {
fetchCopilotUsage,
fetchOpencodeUsage,
getAccountUsage,
+ getAnthropicHeaders,
+ refreshAccountCredentialsAsync,
validateAccountCredentials,
} from "@dispatch/core";
import { Hono } from "hono";
@@ -333,3 +335,46 @@ modelsRoutes.get("/key-usage", async (c) => {
return c.json({ error: `failed to fetch usage: ${message}` }, 502);
}
});
+
+// Wake all Claude accounts by sending "hi" to haiku
+modelsRoutes.post("/wake", async (c) => {
+ const accounts = discoverClaudeAccounts();
+ if (accounts.length === 0) {
+ return c.json({ error: "no Claude accounts available" }, 502);
+ }
+
+ const results: Array<{ label: string; ok: boolean; error?: string }> = [];
+
+ for (const acct of accounts) {
+ try {
+ const creds = await refreshAccountCredentialsAsync(acct);
+ if (!creds) {
+ results.push({ label: acct.label, ok: false, error: "token refresh failed" });
+ continue;
+ }
+
+ const res = await fetch("https://api.anthropic.com/v1/messages", {
+ method: "POST",
+ headers: {
+ ...getAnthropicHeaders(creds.accessToken),
+ "content-type": "application/json",
+ },
+ body: JSON.stringify({
+ model: "claude-3-5-haiku-20241022",
+ max_tokens: 16,
+ messages: [{ role: "user", content: "hi" }],
+ }),
+ });
+
+ results.push({ label: acct.label, ok: res.ok });
+ } catch (err) {
+ results.push({
+ label: acct.label,
+ ok: false,
+ error: err instanceof Error ? err.message : String(err),
+ });
+ }
+ }
+
+ return c.json({ results });
+});