From 3f1a10255d94e17496f923e4f0b12bbea59a4313 Mon Sep 17 00:00:00 2001 From: Anthony Baldwin <6219998+anthonybaldwin@users.noreply.github.com> Date: Sun, 3 May 2026 08:18:24 -0700 Subject: [PATCH] fix: button-spec subvalues + lobe-ify openai/deepseek action art MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two fixes prompted by a review: 1. Subvalue captions now follow Button Spec §7. Was using long sentence-style captions ("Org cost (admin API)", "Avg daily DeepSeek spend (last 7d)"); now uses short, source-tagged captions matching the Claude/Codex "Cost (local)" precedent: - anthropic admin: "Cost (admin)" for the windows, "$/day (7d avg)" for burn rate, "MTD pace" for projected month - openai admin: same as anthropic - deepseek bridge path: "Cost (API)" for the windows (the "API" tag also disambiguates the platform/api source from chat.deepseek.com — DeepSeek's consumer chat product, which has no public usage signal), "$/day (7d avg)", "MTD pace", "Tokens (API)" - deepseek API fallback stubs: "Needs Helper" - deepseek platform error path: "Bridge error" / "Sign in to platform.deepseek.com"; the full error string still lives in Snapshot.Error for the PI / logs 2. Action library + key-preview thumbnails for OpenAI and DeepSeek now use the lobe-icons paths (matching the runtime button-face glyphs from internal/icons/lobe_generated.go). Earlier sync only covered claude + anthropic, leaving openai still on the old rosette and deepseek on the CodexBar-derived whale path. Mirrors the same swap to docs/provider-icons/ for the marketing pills. Display Names also tweaked to clarify DeepSeek = API platform: each metric Name now reads "DeepSeek API …" (e.g. "DeepSeek API balance") so the Property Inspector and tooltips don't conflate the API side with chat.deepseek.com. Co-Authored-By: Claude --- docs/provider-icons/deepseek.svg | 6 +- docs/provider-icons/openai.svg | 6 +- internal/providers/anthropic/anthropic.go | 6 +- internal/providers/deepseek/deepseek.go | 78 ++++++++++--------- internal/providers/openai/openai.go | 6 +- .../assets/action-deepseek-key.svg | 4 +- .../assets/action-deepseek.svg | 6 +- .../assets/action-openai-key.svg | 2 +- .../assets/action-openai.svg | 6 +- 9 files changed, 59 insertions(+), 61 deletions(-) diff --git a/docs/provider-icons/deepseek.svg b/docs/provider-icons/deepseek.svg index bfcad27..96537fd 100644 --- a/docs/provider-icons/deepseek.svg +++ b/docs/provider-icons/deepseek.svg @@ -1,5 +1,3 @@ - - - - + + diff --git a/docs/provider-icons/openai.svg b/docs/provider-icons/openai.svg index 81866ef..fc4b42a 100644 --- a/docs/provider-icons/openai.svg +++ b/docs/provider-icons/openai.svg @@ -1,5 +1,3 @@ - - - - + + diff --git a/internal/providers/anthropic/anthropic.go b/internal/providers/anthropic/anthropic.go index 93bc243..b9860b3 100644 --- a/internal/providers/anthropic/anthropic.go +++ b/internal/providers/anthropic/anthropic.go @@ -261,7 +261,7 @@ func buildMetrics(w costWindows, now string) []providers.MetricValue { projected = round(w.mtd * float64(w.daysInMonth) / float64(w.daysElapsed)) } - caption := "Org cost (admin API)" + caption := "Cost (admin)" return []providers.MetricValue{ { ID: "cost-today", @@ -326,7 +326,7 @@ func buildMetrics(w costWindows, now string) []providers.MetricValue { NumericValue: &burn, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: "Avg daily org spend (last 7d)", + Caption: "$/day (7d avg)", UpdatedAt: now, }, { @@ -337,7 +337,7 @@ func buildMetrics(w costWindows, now string) []providers.MetricValue { NumericValue: &projected, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: fmt.Sprintf("MTD pace through day %d/%d", w.daysElapsed, w.daysInMonth), + Caption: "MTD pace", UpdatedAt: now, }, } diff --git a/internal/providers/deepseek/deepseek.go b/internal/providers/deepseek/deepseek.go index 2679a02..c4b66bb 100644 --- a/internal/providers/deepseek/deepseek.go +++ b/internal/providers/deepseek/deepseek.go @@ -520,13 +520,20 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur gr := round(b.granted) tokens := round(tokensMTD) - costCaption := fmt.Sprintf("Org cost (platform.deepseek.com, %s)", currency) + // Captions follow the Button Spec §7 convention: short, + // source-tagged ("Cost (API)" mirrors Claude/Codex's "Cost + // (local)"). The "API" tag also disambiguates this provider — the + // data describes platform.deepseek.com / api.deepseek.com spend, NOT + // chat.deepseek.com (the consumer chat product, which has no + // public usage signal). + const costCaption = "Cost (API)" + _ = currency // currency is implicit in the symbol; reserved for future CNY/USD subtitle when symbol alone is insufficient return []providers.MetricValue{ { ID: "balance", Label: "BALANCE", - Name: "DeepSeek balance", + Name: "DeepSeek API balance", Value: fmt.Sprintf("%s%.2f", b.symbol, bal), NumericValue: &bal, NumericUnit: "dollars", @@ -537,29 +544,29 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur { ID: "topped-up", Label: "PAID", - Name: "DeepSeek paid balance", + Name: "DeepSeek API paid balance", Value: fmt.Sprintf("%s%.2f", b.symbol, paid), NumericValue: &paid, NumericUnit: "dollars", NumericGoodWhen: "high", - Caption: "Top-up balance", + Caption: "Paid (API)", UpdatedAt: now, }, { ID: "granted", Label: "GRANTED", - Name: "DeepSeek granted balance", + Name: "DeepSeek API granted balance", Value: fmt.Sprintf("%s%.2f", b.symbol, gr), NumericValue: &gr, NumericUnit: "dollars", NumericGoodWhen: "high", - Caption: "Free grant", + Caption: "Granted (API)", UpdatedAt: now, }, { ID: "cost-today", Label: "TODAY", - Name: "DeepSeek spend today (UTC)", + Name: "DeepSeek API spend today (UTC)", Value: fmt.Sprintf("%s%.2f", b.symbol, t), NumericValue: &t, NumericUnit: "dollars", @@ -570,7 +577,7 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur { ID: "cost-yesterday", Label: "YESTERDAY", - Name: "DeepSeek spend yesterday (UTC)", + Name: "DeepSeek API spend yesterday (UTC)", Value: fmt.Sprintf("%s%.2f", b.symbol, y), NumericValue: &y, NumericUnit: "dollars", @@ -581,7 +588,7 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur { ID: "cost-7d", Label: "7 DAYS", - Name: "DeepSeek spend last 7 days", + Name: "DeepSeek API spend last 7 days", Value: fmt.Sprintf("%s%.2f", b.symbol, w7), NumericValue: &w7, NumericUnit: "dollars", @@ -592,7 +599,7 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur { ID: "cost-mtd", Label: "MTD", - Name: "DeepSeek spend month-to-date (UTC)", + Name: "DeepSeek API spend month-to-date (UTC)", Value: fmt.Sprintf("%s%.2f", b.symbol, m), NumericValue: &m, NumericUnit: "dollars", @@ -603,7 +610,7 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur { ID: "cost-30d", Label: "30 DAYS", - Name: "DeepSeek spend last 30 days", + Name: "DeepSeek API spend last 30 days", Value: fmt.Sprintf("%s%.2f", b.symbol, l30), NumericValue: &l30, NumericUnit: "dollars", @@ -619,7 +626,7 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur NumericValue: &burn, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: "Avg daily DeepSeek spend (last 7d)", + Caption: "$/day (7d avg)", UpdatedAt: now, }, { @@ -630,27 +637,27 @@ func buildPlatformMetrics(b parsedBalance, w costWindows, tokensMTD float64, cur NumericValue: &projected, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: fmt.Sprintf("MTD pace through day %d/%d", w.daysElapsed, w.daysInMonth), + Caption: "MTD pace", UpdatedAt: now, }, { ID: "tokens-mtd", Label: "TOKENS MTD", - Name: "DeepSeek tokens used month-to-date", + Name: "DeepSeek API tokens used month-to-date", Value: formatTokens(tokens), NumericValue: &tokens, NumericUnit: "tokens", NumericGoodWhen: "low", - Caption: "Total tokens (input + output) this month", + Caption: "Tokens (API)", UpdatedAt: now, }, } } -// buildAPIMetrics is the legacy-shape metric set surfaced when only -// the public /user/balance endpoint is available. The cost-window -// metric IDs are also emitted (so the picker stays stable) but with -// a "needs Helper extension" caption and zero values. +// buildAPIMetrics is the metric set surfaced when only the public +// /user/balance endpoint is available (no Helper extension). The +// cost-window metric IDs are also emitted (so the picker stays +// stable) but with a "Needs Helper" caption and zero values. func buildAPIMetrics(p parsedBalance, isAvailable bool, now string) []providers.MetricValue { balance := math.Round(p.total*100) / 100 caption := fmt.Sprintf("Paid %s%.2f / Granted %s%.2f", p.symbol, p.toppedUp, p.symbol, p.granted) @@ -658,14 +665,14 @@ func buildAPIMetrics(p parsedBalance, isAvailable bool, now string) []providers. case p.total <= 0: caption = "Add credits at platform.deepseek.com" case !isAvailable: - caption = "Balance unavailable for API calls" + caption = "Balance unavailable" } out := []providers.MetricValue{ { ID: "balance", Label: "BALANCE", - Name: "DeepSeek balance", + Name: "DeepSeek API balance", Value: fmt.Sprintf("%s%.2f", p.symbol, balance), NumericValue: &balance, NumericUnit: "dollars", @@ -679,12 +686,12 @@ func buildAPIMetrics(p parsedBalance, isAvailable bool, now string) []providers. out = append(out, providers.MetricValue{ ID: "topped-up", Label: "PAID", - Name: "DeepSeek paid balance", + Name: "DeepSeek API paid balance", Value: fmt.Sprintf("%s%.2f", p.symbol, paid), NumericValue: &paid, NumericUnit: "dollars", NumericGoodWhen: "high", - Caption: "Top-up balance", + Caption: "Paid (API)", UpdatedAt: now, }) @@ -692,25 +699,25 @@ func buildAPIMetrics(p parsedBalance, isAvailable bool, now string) []providers. out = append(out, providers.MetricValue{ ID: "granted", Label: "GRANTED", - Name: "DeepSeek granted balance", + Name: "DeepSeek API granted balance", Value: fmt.Sprintf("%s%.2f", p.symbol, gr), NumericValue: &gr, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: "Free grant", + Caption: "Granted (API)", UpdatedAt: now, }) - // Stub the cost-window + token metrics with a "needs Helper" caption - // so users see where the richer data would come from. - stubCaption := "Connect Usage Buttons Helper to platform.deepseek.com for cost windows" + // Stub the cost-window + token metrics with a short "Needs Helper" + // caption — long-form explanation belongs in the tooltip and docs. + const stubCaption = "Needs Helper" zero := 0.0 for _, id := range []string{"cost-today", "cost-yesterday", "cost-7d", "cost-mtd", "cost-30d", "cost-burn-7d", "cost-projected-month"} { v := zero out = append(out, providers.MetricValue{ ID: id, Label: costStubLabel(id), - Name: "DeepSeek " + costStubName(id) + " (Helper extension required)", + Name: "DeepSeek API " + costStubName(id) + " (Helper extension required)", Value: fmt.Sprintf("%s%.2f", p.symbol, v), NumericValue: &v, NumericUnit: "dollars", @@ -723,7 +730,7 @@ func buildAPIMetrics(p parsedBalance, isAvailable bool, now string) []providers. out = append(out, providers.MetricValue{ ID: "tokens-mtd", Label: "TOKENS MTD", - Name: "DeepSeek tokens used month-to-date (Helper extension required)", + Name: "DeepSeek API tokens used month-to-date (Helper extension required)", Value: formatTokens(tokens), NumericValue: &tokens, NumericUnit: "tokens", @@ -736,16 +743,15 @@ func buildAPIMetrics(p parsedBalance, isAvailable bool, now string) []providers. } // platformErrorSnapshot wraps a platform-bridge error into a snapshot -// with a clear caption so users see what went wrong (e.g., "no -// platform tab open" vs "token expired"). +// with a short caption per Button Spec §7. The full error string lives +// in Snapshot.Error for the Property Inspector and logs; on the tile +// itself we just say "Bridge error" so the subvalue stays one line. func platformErrorSnapshot(err error) providers.Snapshot { now := providerutil.NowString() zero := 0.0 - caption := "Sign in to platform.deepseek.com (extension reads userToken from the open tab)" + caption := "Sign in to platform.deepseek.com" if err != nil { - // Surface the real error in the caption — useful for diagnosing - // "token expired" vs "no tab open" without requiring logs. - caption = "DeepSeek platform: " + err.Error() + caption = "Bridge error" } out := []providers.MetricValue{ { diff --git a/internal/providers/openai/openai.go b/internal/providers/openai/openai.go index c3e3191..3b5d647 100644 --- a/internal/providers/openai/openai.go +++ b/internal/providers/openai/openai.go @@ -266,7 +266,7 @@ func buildMetrics(w costWindows, now string) []providers.MetricValue { projected = round(w.mtd * float64(w.daysInMonth) / float64(w.daysElapsed)) } - caption := "Org cost (admin API)" + caption := "Cost (admin)" return []providers.MetricValue{ { ID: "cost-today", @@ -331,7 +331,7 @@ func buildMetrics(w costWindows, now string) []providers.MetricValue { NumericValue: &burn, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: "Avg daily org spend (last 7d)", + Caption: "$/day (7d avg)", UpdatedAt: now, }, { @@ -342,7 +342,7 @@ func buildMetrics(w costWindows, now string) []providers.MetricValue { NumericValue: &projected, NumericUnit: "dollars", NumericGoodWhen: "low", - Caption: fmt.Sprintf("MTD pace through day %d/%d", w.daysElapsed, w.daysInMonth), + Caption: "MTD pace", UpdatedAt: now, }, } diff --git a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek-key.svg b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek-key.svg index df10944..51d9b37 100644 --- a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek-key.svg +++ b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek-key.svg @@ -1,6 +1,6 @@ - - + + diff --git a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek.svg b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek.svg index bfcad27..96537fd 100644 --- a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek.svg +++ b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-deepseek.svg @@ -1,5 +1,3 @@ - - - - + + diff --git a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai-key.svg b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai-key.svg index fe7d50b..7b69e39 100644 --- a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai-key.svg +++ b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai-key.svg @@ -1,6 +1,6 @@ - + diff --git a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai.svg b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai.svg index 81866ef..fc4b42a 100644 --- a/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai.svg +++ b/io.github.anthonybaldwin.UsageButtons.sdPlugin/assets/action-openai.svg @@ -1,5 +1,3 @@ - - - - + +