diff options
| author | Adam Malczewski <[email protected]> | 2026-05-20 23:37:01 +0900 |
|---|---|---|
| committer | Adam Malczewski <[email protected]> | 2026-05-20 23:37:01 +0900 |
| commit | 1f4776e6891348d2dbdcbbf704c0a5901b008ecf (patch) | |
| tree | d406c2ba412b5393b16a3f9253acea34807d0dda /packages/api/src | |
| parent | 29e4c2db4555bb764f458971f0c591c092e30ed6 (diff) | |
| download | dispatch-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/src')
| -rw-r--r-- | packages/api/src/routes/models.ts | 45 |
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 }); +}); |
