The task-log and MJ task ID cells used a w-max wrapper, so long IDs
(and the platform/action subtitle) overflowed the column and rendered
under the adjacent Cost column. Constrain the cell to the column width
and let the badge label ellipsize; the copy button still copies the
full ID.
Merge origin/main (48068ce92). The backend billing feature merged
cleanly; the single frontend conflict was a grid ratio tweak to the
old-design mobile log card, which does not exist in our generic
card layout, so our version is kept.
Parse OpenAI's native cache_write_tokens (chat prompt_tokens_details /
responses input_tokens_details), bill it at the cache-creation ratio, and
clamp the uncached prompt remainder at zero since cached + cache-write can
exceed prompt_tokens. Propagate the field through chat/responses/claude
format conversions and tiered expression billing (cc variable).
Merge origin/main (c36418c86, text protocol conversion and advanced
custom routing). Backend and most frontend changes merged cleanly;
conflicts resolved with refactor/ui as the design source of truth:
- advanced-custom-editor-dialog: keep main new routing/conversion
feature body, but use our design-system Button/Input imports and
plain button styling; add the Badge import the new body needs
- details-dialog: adopt main isUsageBillingPathLocal helper for the
billing path row, keep our muted icon styling
- i18n: union-merge of the new protocol-conversion keys across all
locales
* refactor: consolidate relay protocol converters
* refactor relayconvert text converters
* feat: refine relay converters and advanced custom routing
* refactor: enhance logging and add thought signature handling for Gemini requests
* refactor: enhance channel cache and pricing endpoint handling for advanced custom models
* feat: preserve billing usage semantics
* feat: add protocol-aware billing usage
* Delete useless files
* chore: update action versions in workflow files
* chore: update Docker action versions in workflow files
* fix: harden billing usage settlement and hot-path route matching
- estimate Gemini completion tokens locally when billable usageMetadata is
prompt-only but output content was received (e.g. client aborts the stream
before the final chunk), and rebuild the attached billing_usage as estimated
so settlement does not bill zero output tokens
- guard NewClaudeMessagesBillingUsage against all-zero ClaudeUsage, matching
the OpenAI/Gemini constructors, so a zero billing_usage cannot override a
non-zero top-level usage during settlement
- cache compiled advanced-custom route model regexes; they run on the request
hot path and were recompiled per request
- move the effectiveBillingUsage remap to PostTextConsumeQuota only, and
document that calculateTextQuotaSummary expects remapped usage
- document the updatePricingLock -> channelSyncLock lock ordering that
InitChannelCache/CacheUpdateChannel rely on, and the aux-struct pitfall in
GeminiChatResponse.UnmarshalJSON
1250fb2eb adds -ml-1.5 padding compensation to the old-design logs Time
badge; our plain StatusBadge has no horizontal padding so the offset
does not apply. Style follows refactor/ui.
Amends the merge resolution: drop the duplicated copy icon/tooltip block
that main reintroduced in ApiKeyCell (ours already declares it with the
text-success token), and port the functional change from main e40061965
that hides the Delete all stale button entirely when no stale instances
exist instead of rendering it disabled.
Merge origin/main while keeping this branch as the source of truth for
UI/UX. The design-system revert (337169e0a) and StatusBadge padding
revert (1b1b23d1d) from main were absorbed without applying them; only
functional additions were ported and re-styled with our primitives:
- usage-logs: Stream/Timing column split with new TimingMetricsCell and
StreamTpsCell (first-token latency + duration readout, t/s line),
admin All/Only Mine view scope (useLogsViewScope), and a mobile
filter-panel collapse toggle in DataTableFilterPanel
- keys: relative timestamps with absolute-time tooltip and stale-access
highlight via ApiKeyTimestampCell (auto-refreshing now ticker), and
copy button that resolves the real key on demand
- pricing: ModelBillingModeBadge distinguishing dynamic pricing from
token/per-request billing in the Type column
- i18n: First token translations for all locales
Rejected from main: icon-badge tones, overview accent theme colors,
bespoke mobile lists (redemptions/keys), and all other styling that
conflicts with the refactor/ui design language.
Records 337169e0a (revert of the design-system refactor) and 1b1b23d1d
(revert of StatusBadge padding) as merged while keeping the refactor/ui
tree unchanged. This branch is the source of truth for UI/UX design;
functional additions from main are merged separately.
Keep truncated cells single-line across data tables, compact oversized quota figures, and replace loud avatar gradients with identity-tint styling that matches badges.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Replace self-hosted @font-face declarations (font-display: optional) with
direct Fontsource imports (swap), so the UI always settles on bundled
fonts instead of staying on system fonts after first paint
- Add JetBrains Mono (@fontsource-variable/jetbrains-mono) as the built-in
monospace face: it backs --font-mono, .font-mono utilities, and code/pre
- Add a "mono" option to the theme font axis (CSS token, ThemeFont type,
resolver, and config drawer with live preview); default body font stays
Public Sans, Anthropic preset keeps Lora serif
- Lighten --subtle-foreground/--faint-foreground in light mode to 60%/40%
translucent mixes of muted-foreground so secondary metadata (log
sub-labels, placeholders) reads properly grey; declare once since the
var() reference resolves per light/dark mode on <html>
Revert 6869cd94b (perf(web): align table badge spacing).
Restores px padding on status badges so usage-log timing/duration
pills are not flush against the edges.
The custom home page URL iframe only allows allow-forms/allow-popups/
allow-popups-to-escape-sandbox/allow-scripts, without allow-top-navigation*.
As a result, target="_top" nav/menu links inside the (admin-configured,
trusted) embedded page cannot navigate the top-level window on desktop
browsers, while some mobile browsers still allow it via allow-popups —
causing inconsistent behavior rather than an intended restriction.
Add allow-top-navigation-by-user-activation so user-clicked top-level
links work consistently across devices. This token only permits
user-activated top navigation and does NOT grant same-origin access,
so it avoids the security concern of allow-same-origin.
Co-authored-by: 贺. <kuang@M1.local>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace collapsible card details with always-visible label/value rows, add badge-list full display for cards, and polish pricing/channel toolbars and mobile cards.
- remove built-in horizontal padding from status badges so table columns align with headers.
- drop legacy negative-margin compensation from badge cells and affected table renderers.
- clean touched table components to satisfy lint rules around type imports, keys, and JSX flow.
- keep input focus and invalid rings inside the shared Input component to avoid clipping in constrained containers.
- make the sync channel selector table use a fixed header, internal body scrolling, and fixed pagination inside the dialog.
- align status cells with their header and translate channel status labels through existing i18n keys.
- batch select and unselect operations into single state updates to reduce lag with large model lists.
- align current price and upstream preset rows by rendering the same ordered field set.
- switch the table to a fixed header, internal body scrolling, and fixed pagination layout with compact upstream header counts.
- hide synthesized preset internal IDs and count only effective selectable resolutions.
- expose playground controls for sampling, penalty, token, and seed parameters.
- reuse the existing persisted config and parameter-enabled state so requests only send enabled values.
- add localized parameter copy and keep the panel scrollable on short screens.
controller/task_video.go and service/pre_consume_quota.go were already
removed in ba25ba88f and 116004fd4 (logic lives in service/task_polling.go
and BillingSession now), then brought back as stale copies by a42b39760.
Both have zero callers.
controller/swag_video.go is a leftover swag stub: the swaggo pipeline is
gone and docs/openapi/relay.json already documents these routes.
- constrain the desktop selector panel so long group and model lists scroll within a shared height.
- make the selected model stand out with stronger row and label styling.
- scroll both lists to the active selections after the popover opens.