Commit Graph

3063 Commits

Author SHA1 Message Date
diegosouzapw
6fa745efcb chore: untrack .claude/scheduled_tasks.lock + ignore runtime artifacts
The lockfile is local Claude Code session state that was committed by
accident in 24b2e77a (#2265). Untrack it and add a narrow .gitignore rule
covering only runtime artifacts (lock, scheduled_tasks, sessions, state)
so shared command definitions at .claude/commands/ stay tracked.
2026-05-17 03:03:57 -03:00
diegosouzapw
440ca8e3cc Merge pull request #2314 from oyi77/feat/gitlawb-opengateway
feat: gitlawb opengateway provider + providers page filter chips

Three independent contributions from oyi77 bundled in this PR:

1. Gitlawb Opengateway provider (b83d1a0fc):
   - gitlawb (alias glb) — xiaomi-mimo endpoint with 5 MiMo models
   - gitlawb-gmi (alias glb-gmi) — gmi-cloud endpoint with 40+ models
   - Both flagged free tier, CLI-mimicking headers to avoid upstream
     rate limiting
   - 9 unit tests in tests/unit/gitlawb-provider.test.ts (all green)

2. hasFree flag (d7dcd233a): friendliai, chutes, featherless-ai now
   correctly surface free tier badge in the providers page.

3. UI additions (debf7cb28):
   - CollapsibleSection.tsx (coexists with our existing Collapsible.tsx —
     different API for different use cases)
   - Category filter chips bar on /dashboard/providers (auto-merged)
   - Free-only toggle on /dashboard/providers (auto-merged)
   - Extended filterConfiguredProviderEntries with showFreeOnly param
   - i18n tooltip keys for Caveman/RTK settings (union with our
     simpleMode/advancedMode/filterCatalog keys)
   - InfoTooltip + PresetSlider identical to PR #2316 versions
     (silent dedup by auto-merge)

Conflict resolution:
- src/shared/components/index.tsx: union — added CollapsibleSection
  export alongside our NoAuthProviderCard.
- src/i18n/messages/en.json: union — kept all our keys from #2316
  (simpleMode/advancedMode/filterCatalog/filterCatalogDesc) and added
  PR's tooltip keys (searchFilters, tooltipDedup, tooltipMaxChars,
  tooltipMaxLines, tooltipAutoTrigger, tooltipCompressionRate,
  tooltipMaxTokens, tooltipMinLength, tooltipMinSavings, ultraSettings,
  ultraSettingsDesc).

Closes #2314
2026-05-17 02:37:05 -03:00
diegosouzapw
43d4ea092c Merge pull request #2316 from oyi77/feat/ui-rework
feat(ui): simple/advanced mode for Caveman & RTK + newbie UX improvements

Adapts oyi77's UX rework on top of our refactor/pages overhaul. Layout
priority: our 9-section sidebar restructure stays; PR's additions
(subtitles, intros, simple/advanced toggles, empty states, error labels)
are integrated into our structure.

Conflict resolution:

- index.tsx: union — exports InfoTooltip, PresetSlider (new shared
  components from PR) alongside our NoAuthProviderCard.
- en.json: union — kept our "OmniSkills"/"AgentSkills" labels and
  "API Key Manager" naming; added PR's subtitleKey strings, settings
  intro keys, and empty state keys.
- sidebarVisibility.ts: kept our 9-section structure; added subtitleKey?:
  string to SidebarItemDefinition and mapped subtitle keys onto the 7
  matching items (endpoints, api-manager, combos, batch, context-caveman,
  context-rtk, webhooks).
- Sidebar.tsx: kept our collapsible-section rendering; integrated PR's
  subtitle support into resolveItem() and renderNavLink() label area.
- CavemanContextPageClient.tsx: took PR's version — adds SegmentedControl
  for simple/advanced mode (gates full settings tab in advanced).
- RtkContextPageClient.tsx: took PR's version — adds SegmentedControl +
  Collapsible filter catalog.
- settings/page.tsx: kept our redirect (we converted tabs→pages). Ported
  PR's intro text paragraphs to /settings/ai, /settings/routing, and
  /settings/resilience subpages using the auto-merged i18n keys.
- HomePageClient.tsx: kept ours — we removed Providers Overview card in
  the refactor, and PR's empty state for that card is now redundant.
  PR's equivalent empty state at /dashboard/providers (in
  providers/page.tsx) auto-merged cleanly and serves the same purpose.

Closes #2316
2026-05-17 02:13:22 -03:00
Diego Rodrigues de Sa e Souza
ee2a698dcb Merge pull request #2315 from diegosouzapw/refactor/pages
refactor(dashboard): pages overhaul, providers UX, OAuth token refresh fixes [deferred in develop]
2026-05-17 01:44:30 -03:00
diegosouzapw
317d146302 Merge release/v3.8.0 into refactor/pages
Resolves conflicts in 9 files to bring 181 commits from release/v3.8.0 into
the dashboard refactor branch ahead of merging back to release.

Layout strategy: our pages overhaul (tabs→pages, restructured sidebar,
removed redundant headers, OpenCode Free no-auth card) is the source of
truth. Release's functional additions are adapted into our layout.

Conflict resolution:

- package.json/package-lock.json: take release's deps (axios bump, CLI v4
  deps, tls-client-node/wreq-js move to optionalDependencies); re-add our
  @xyflow/react addition; regenerate lockfile.
- src/shared/constants/sidebarVisibility.ts: keep our 9-section restructure
  — release's new IDs (limits, media, cli-tools, agents, cloud-agents,
  memory, skills, agent-skills, context-*) are all already present in our
  groups.
- src/i18n/messages/en.json: auto-merge picked up all release's new keys
  (autoCatalog*, quotaCutoffs*, systemTransforms*, schema-coercion, vision);
  only naming conflict was OmniSkills/AgentSkills — kept ours (no space).
- src/app/(dashboard)/dashboard/HomePageClient.tsx: kept our Provider
  Topology card; ported release's TierCoverageWidget (placed before
  topology).
- src/app/(dashboard)/dashboard/settings/page.tsx: kept our redirect to
  /settings/general (we moved tabs to separate pages); release's sticky
  tab CSS change is moot in our structure.
- src/app/(dashboard)/dashboard/skills/page.tsx: rerere applied — release
  hardcoded "OmniSkills" h1 was already removed by our header-cleanup
  refactor.
- src/app/(dashboard)/dashboard/agent-skills/page.tsx: both branches
  created this file independently with identical data source; kept our
  Tailwind-themed 2-column grid (release's version used inline styles).
- src/app/(dashboard)/dashboard/batch/page.tsx: kept our single-tab
  structure (FilesListTab moved to /batch/files page); ported release's
  onRefresh prop addition.
- src/app/(dashboard)/dashboard/batch/files/page.tsx (not in conflict but
  updated): added batches fetch + batches prop to preserve release's
  feature of showing related batches in the file detail modal.

Pre-existing typecheck errors in open-sse/services/contextManager.ts
(lines 141, 154, 167) come from release/v3.8.0 and are not introduced by
this merge.
2026-05-17 01:14:21 -03:00
oyi77
a4a870cda3 feat(ui): add newbie-friendly UX improvements across dashboard
- Providers page: empty state with guided 'Add your first provider' card
- Providers page: home page shows only configured providers by default
- Settings: add intro text to Routing, Resilience, and AI tabs
- i18n: fix 'Api Key Mgmt' to 'API Key Management', remove duplicate key
- i18n: add keys for empty state, settings intros, free-only filter
2026-05-17 07:56:22 +07:00
diegosouzapw
2b624b1bf3 chore(changelog): add entries for PRs #2317, #2318, #2319 2026-05-16 21:51:48 -03:00
backryun
cf3262aee8 alibaba provider consolidation (#2319)
Integrated into release/v3.8.0 — consolidates Alibaba-related providers, updates model registries and docs.
2026-05-16 21:50:59 -03:00
backryun
926ff2b5db chore(providers): refresh provider metadata and ordering (#2318)
Integrated into release/v3.8.0 — refreshes provider model metadata, sorts dashboard provider entries by display name, and fixes docs generator relative links.
2026-05-16 21:48:01 -03:00
Raxxoor
5a7df8ac29 fix: harden stream readiness and build output (#2317)
Integrated into release/v3.8.0 — fixes stream readiness detection for OpenAI Responses API lifecycle events, GLM timeout, Provider Limits UI, and build output cleanup.
2026-05-16 21:47:40 -03:00
diegosouzapw
7fdcba9e05 fix(auth): return synthetic credentials for noAuth free providers
Requests to opencode (noAuth: true) were failing with "No credentials for
provider: opencode" because getProviderCredentials found no DB connections and
returned null — triggering the 400 error path in chatHelpers.

Inject a synthetic credential object (connectionId: "noauth", no apiKey/token)
before the regular connection lookup so the executor receives valid credentials
and skips the Authorization header. Also enable model import for noAuth providers
(canImportModels = true when isFreeNoAuth).
2026-05-16 21:31:03 -03:00
diegosouzapw
42011abc69 fix(auth): include connection id in token health check credentials
Pass the connection identifier along with token credentials during
connection checks so downstream auth flows can use the full context
for refresh and validation behavior.
2026-05-16 21:20:28 -03:00
diegosouzapw
fd28e772a8 fix(dashboard): show no-auth card for free providers instead of OAuth modal
OpenCode Free (noAuth: true) was routed through OAuthModal which tried to call
a non-existent /api/oauth/opencode/authorize endpoint, resulting in a 500 error.

Detect noAuth free providers via FREE_PROVIDERS[id]?.noAuth and render a
NoAuthProviderCard (lock_open + description) instead of the connections section
with the "+ Add" button that triggered the broken flow.
2026-05-16 21:05:49 -03:00
oyi77
8a23c5527e feat(ui): replace cryptic error badges with human-readable labels
Replace AUTH/429/5XX/NET/RUNTIME with Auth/Rate limited/Server
error/Network/Runtime in provider error badges.
2026-05-17 05:58:41 +07:00
oyi77
13ca2cc62a feat(ui): add sidebar item subtitles for confusing navigation items
Add subtitleKey to SidebarItemDefinition and render subtitles under
sidebar labels for: Endpoints, API Manager, Combos, Batch, Caveman,
RTK, and Webhooks. Helps non-technical users understand navigation.
2026-05-17 05:56:05 +07:00
oyi77
8afaca4b9f feat(i18n): add simple/advanced mode keys for Caveman and RTK pages 2026-05-17 05:41:50 +07:00
oyi77
3757e6dc30 feat(ui): add simple/advanced mode switch to RTK page
Simple mode shows stats, config, and collapsible filter catalog.
Advanced mode adds filter testing with raw JSON preview.
2026-05-17 05:38:04 +07:00
oyi77
801f3c9c22 feat(ui): add simple/advanced mode switch to Caveman page
Simple mode shows stats, language packs, and output mode only.
Advanced mode reveals the full CompressionSettingsTab with all
engine internals, thresholds, and tool strategies.
2026-05-17 05:35:41 +07:00
oyi77
8669bf69ec feat(ui): add InfoTooltip and PresetSlider shared components 2026-05-17 05:33:27 +07:00
oyi77
debf7cb283 feat(ui): add shared components + providers page category filter
- Add CollapsibleSection, InfoTooltip, PresetSlider shared components
- Add category filter chips bar to providers page
- Add free-only toggle to providers page
- Extend filterConfiguredProviderEntries with showFreeOnly param
- Add i18n keys for Caveman/RTK tooltips and labels
2026-05-17 05:25:47 +07:00
diegosouzapw
7e9efe7cb0 chore(changelog): add missing entries #2283, #2284, #2285, #2279, #2228 and translate PT→EN 2026-05-16 19:24:48 -03:00
oyi77
d7dcd233a2 feat(provider): add hasFree flag to friendliai, chutes, featherless-ai 2026-05-17 05:24:11 +07:00
oyi77
b83d1a0fc8 feat(provider): add Gitlawb Opengateway provider (xiaomi-mimo + gmi-cloud)
Add two OpenAI-compatible API-key providers via the Gitlawb Opengateway
gateway at opengateway.gitlawb.com:

- gitlawb (alias glb): xiaomi-mimo endpoint with 5 MiMo models
- gitlawb-gmi (alias glb-gmi): gmi-cloud endpoint with 40+ models
  including GPT-5.x, Claude 4.x, DeepSeek, Gemini, Qwen, GLM, Kimi

Both providers include CLI-mimicking headers (User-Agent, X-Title,
HTTP-Referer) to avoid upstream rate limiting. GMI Cloud provider
has passthroughModels enabled since model access varies per API key.
2026-05-17 05:24:11 +07:00
diegosouzapw
08f03a0fa6 fix(auth): stop retrying unrecoverable token refresh failures
Propagate invalid refresh-token errors instead of collapsing them to null
so callers can distinguish expired credentials from transient failures.

Mark affected connections as expired and inactive when refresh fails
with an unrecoverable error, and persist that state during credential
updates. Add tests covering retry bail-out and Claude/Codex refresh
error handling.
2026-05-16 19:12:58 -03:00
diegosouzapw
56b0ea91c9 fix(endpoint): replace nested <button> with <div role=button> in tunnel toggle rows
Tailscale and ngrok expandable rows used <button> as outer container while also
containing inner <button> elements (copy URL, action buttons). Nested buttons are
invalid HTML and caused a React hydration error that prevented the app from
loading in the browser (stuck on Loading... spinner).
2026-05-16 17:46:50 -03:00
diegosouzapw
bbfd3865a5 chore(changelog): update for PRs #2313, #2312, #2309 2026-05-16 17:42:35 -03:00
Markus Hartung
dae0501d75 fix: remove count from batch removal (#2309)
Integrated into release/v3.8.0
2026-05-16 17:39:50 -03:00
Mourad Maatoug
8eb721ec31 fix(claude): guard orphan tool_use/tool_result pairs before upstream send (#2312)
Integrated into release/v3.8.0
2026-05-16 17:39:47 -03:00
backryun
ebef1648be chore: Imporve cohere provider support (#2313)
Integrated into release/v3.8.0
2026-05-16 17:39:44 -03:00
diegosouzapw
1640530ec8 fix(config): replace wildcard 192.168.* with exact IP in allowedDevOrigins
Next.js does not support glob patterns in allowedDevOrigins, so the wildcard
was silently ignored — blocking HMR access from 192.168.0.250 and causing an
infinite loading spinner on the login page when accessed from the LAN.
2026-05-16 17:38:30 -03:00
diegosouzapw
4913439d91 fix(dashboard): fix search icon alignment and widen search field in providers page
- Use Input's built-in icon prop so the search icon renders inside the correct
  positioned context (Input's internal div.relative) instead of misaligned outside
- Switch from className to inputClassName so padding applies to the actual <input>
  element, not the outer wrapper div
- Remove flex-1 spacer; make search container flex-1 so it fills available width
2026-05-16 17:21:55 -03:00
diegosouzapw
789a263967 feat(dashboard): provider summary card, free test btn, sidebar order, i18n fix
- sidebarVisibility: move endpoints before api-manager
- en.json: add freeTierProviders/Label/Desc + providerSummaryAll to providers namespace
- page.tsx: apply showConfiguredOnly filter to free tier section (was hardcoded false)
- page.tsx: replace search bar with summary Card containing:
    search (25%) + configured-only toggle + test-all button / dot legend / stats row
    stats show Total / Free / OAuth / API Key configured/total counts
- page.tsx: add batch test button to Free Tier Providers section header
- page.tsx: remove duplicate configured-only toggle from OAuth section header
- page.tsx: import Card component
2026-05-16 15:53:37 -03:00
diegosouzapw
f224b9f104 fix(dashboard): correct dot colors per provider type + search/legend bar
- ProviderCard: add cloud-agent dot (violet) to DOT_COLORS
- page.tsx: web-cookie/search/audio/cloud-agent/local/upstream-proxy
  sections now pass their actual type as authType instead of displayAuthType
  (which was always "apikey" for all static catalog groups)
- page.tsx: split search bar row into 25% input + 75% dot-type legend
  showing all 10 auth types with their colors and translated labels
2026-05-16 13:53:18 -03:00
diegosouzapw
f80de415ec docs(changelog): add entry for PR #2308
- Add auth+build fix entry to [Unreleased]
- Update @mrmm PR count (2 -> 3)
2026-05-16 13:29:50 -03:00
Mourad Maatoug
ec138c6fee fix(auth+build): Bearer manage scope on management routes + lazy-load deepseek PoW solver (#2308)
Integrated into release/v3.8.0
2026-05-16 13:28:57 -03:00
diegosouzapw
b3b006b630 fix(dashboard): compact empty state, remove free badges, shrink toggle
- ProviderCard: remove Free Tier badge (dots already indicate type/free)
- ProviderCard: add dual-dot for providers with hasFree + paid authType
- ProviderCard: font-size xs for name, Toggle shrunk to size xs
- Toggle: add xs size variant (w-6 h-3 track, 8px thumb)
- page.tsx: compact Compatible Providers empty state (single inline line)
2026-05-16 12:25:02 -03:00
josephvoxone
04335c5a6b fix: remove implicit API key request caps (#2289)
Conflicts resolved and integrated into release/v3.8.0. Thanks again!
2026-05-16 12:12:53 -03:00
diegosouzapw
c15ea65a26 docs(changelog): add entry for PR #2305
- Add v3.8.0 ui polish fixes entry to [Unreleased]
- Update @mrmm PR count (1 -> 2)
2026-05-16 12:07:00 -03:00
Mourad Maatoug
2af6923e6e fix(ui): v3.8.0 polish — connections border, sticky tabs, EN translations, save toasts, auto-combo catalog (#2305)
Integrated into release/v3.8.0
2026-05-16 12:06:12 -03:00
diegosouzapw
9ccb7b1c1e fix(dashboard,sse): correct opencode free provider and free section dot color
Add passthroughModels: true to the opencode registry entry so that unknown
model IDs trigger model lockout instead of connection cooldown. Fix dot color
for FREE_PROVIDERS in the Free Tier section by using toggleAuthType === "free"
to select the green dot instead of the blue oauth dot.
2026-05-16 12:01:31 -03:00
diegosouzapw
51918cb5d4 feat(dashboard): providers page — custom section to top, smaller cards, free tier section
Moves Compatible Providers to the top (before Expiration Banner) so users can
add custom OpenAI/Anthropic compatible providers without scrolling. Reduces
ProviderCard icon from 32px to 28px and increases grid density by one column at
each breakpoint (gap-4→gap-3). Adds a curated Free Tier Providers section with
27 providers (OAuth/noAuth group + API-key free-tier group), positioned between
Expiration Banner and OAuth Providers. Cards in the free section suppress the
hasFree badge since context makes it implicit.
2026-05-16 11:31:02 -03:00
diegosouzapw
91af593bb2 feat(dashboard,sse): add OpenCode Free provider (noAuth, public endpoint)
Adds 'opencode' to FREE_PROVIDERS as a no-auth provider using the public
OpenCode endpoint (https://opencode.ai/zen/v1). The existing OpencodeExecutor
already skips the Authorization header when no API key is present. Registry
entry reuses the opencode executor and shares models from the zen/v1 endpoint.
2026-05-16 11:29:57 -03:00
diegosouzapw
9efad44fc9 docs(changelog): add missing entries for PRs #2286, #2288, #2289, #2290, #2291, #2294, #2295, #2299
- Add 8 missing contributor PR entries to [Unreleased] section
- Add 3 new contributors to the community table:
  @thepigdestroyer (2 PRs), @josephvoxone (1 PR), @mrmm (1 PR)
- Update counts: @oyi77 12→14, @backryun 8→9, @ddarkr 3→4,
  @hartmark 2→4
- Compensates for cherry-picked PRs that couldn't be properly
  merged via GitHub (branch deleted or fork restriction)
2026-05-16 10:52:46 -03:00
diegosouzapw
367497958f feat(endpoints): grid layout for Available Endpoints card, add 4 missing endpoints
Layout change:
- Replace accordion (EndpointSection) with compact grid cards (EndpointCard)
  showing icon, title, model count badge, path, and copy URL in 2–4 columns
- All 17 endpoints now visible at once without expand/collapse

Missing endpoints added:
- /v1/messages — Anthropic Messages API native format (badge: Anthropic)
- /v1/images/edits — Image editing/inpainting (shares image models)
- /v1/batches — OpenAI-compatible Batch API (badge: OpenAI)
- /v1/files — Files API for batch job management

Counter fix:
- Remove hardcoded +2 hack; compute count precisely:
  chat×4 (chat/responses/completions/messages) + image×2 (gen+edits)
  + per-category media + 3 fixed utility (batch/files/list-models)
  + model-based utility + search

i18n: add messagesApi, imageEdits, batchApi, filesApi keys to endpoint namespace
2026-05-16 10:27:15 -03:00
diegosouzapw
b3baa0e9f4 docs(changelog): document #2281 #2300 #2298 #2292 fixes 2026-05-16 10:16:33 -03:00
diegosouzapw
56d6ad604c fix(opencode-zen): flag qwen3.6-plus(-free) as targetFormat=claude (#2292)
opencode-zen returns Claude-format SSE bodies (type: 'message_start', no
choices array) for qwen3.6-plus and qwen3.6-plus-free even when the request
hits the OpenAI-compatible /chat/completions endpoint. Clients expecting
OpenAI format fail Zod validation with 'expected choices (array), received
undefined'.

Flagging these two models with targetFormat: 'claude' makes the opencode
executor route through /messages and the response is parsed by the Claude
translator. This matches the existing minimax-m2.7/m2.5 pattern in
opencode-zen and is the minimum-risk fix that ships in v3.8.0.

The broader runtime format-detection refactor proposed by @raccoonwannafly
(detect Claude payload on 200 response from OpenAI endpoint) is deferred
to a dedicated PR with end-to-end tests.
2026-05-16 10:15:46 -03:00
diegosouzapw
52222aaf76 fix(embeddings/registry): add DeepInfra to embedding provider registry (#2298)
Custom embedding models on the DeepInfra provider (e.g.
Qwen/Qwen3-Embedding-8B) were rejected by createEmbeddingResponse with
'Unknown embedding provider: deepinfra. No matching hardcoded or local
provider found.' because the registry only included Nebius/OpenAI/Together/
Fireworks/NVIDIA/Mistral/Voyage/Jina/Gemini. The fallback to
provider_nodes only resolves localhost/172.x dev URLs, so remote DeepInfra
keys had no path to /v1/embeddings.

Adds DeepInfra with 8 popular embedding models (Qwen3-Embedding-8B/4B/0.6B,
BGE Large/Base/M3, E5 Large v2, GTE Large) routed through
https://api.deepinfra.com/v1/openai/embeddings.

Part 1 (incomplete model list import) still needs reproduction details
from the reporter and will be tracked separately.
2026-05-16 10:14:57 -03:00
diegosouzapw
124ed82f02 fix(api/combos): add API-key-safe GET /v1/combos endpoint (#2300)
The existing /api/combos GET requires a management token, which broke
read-only integrations (opencode-omniroute-auth plugin and similar) that
need to enrich combo capabilities from a normal Bearer API key. Those
clients got 403 AUTH_001 'Invalid management token' even though the same
API key could list models via /v1/models.

This adds GET /v1/combos with the same auth model as /v1/models:
- Accepts valid Bearer API key OR dashboard session cookie.
- Falls back to anonymous when REQUIRE_API_KEY=false (single-user local).
- Projects ONLY public metadata: name, strategy, description, model id,
  providerId, comboName (for combo-refs). Internal routing details
  (connectionId, weights, labels, sortOrder, config) are stripped.

/api/combos (management writes) is unchanged.
2026-05-16 10:14:06 -03:00
diegosouzapw
50ad3b0e22 fix(translator): map developer→system by default for non-openai providers (#2281)
The OpenAI Responses API path emits 'developer' role messages. The previous
default preserved that role for any targetFormat=openai upstream, which broke
DeepSeek, MiniMax, Mimo, GLM, Fireworks, Together, and most other
OpenAI-compatible gateways with '[400]: unknown variant developer, expected
one of system/user/assistant/tool'.

New default: preserve developer only for the openai-family allowlist
(openai, azure-openai, azure, github, or any id containing 'openai').
Convert developer→system for everyone else when preserveDeveloperRole is
not explicitly set. The dashboard 'Compatibility → preserveOpenAIDeveloperRole
= true' toggle still forces preservation when needed.
2026-05-16 10:13:08 -03:00
diegosouzapw
beb43a8bea feat(dashboard): add A2A audit page, stats bar on MCP audit, fix sidebar duplicates
- Add /dashboard/audit/a2a page with A2aAuditTab: lists tasks with skill/state
  filters, colored state badges, duration, events and artifacts counts
- Add "A2A Audit" item to Audit sidebar group (Monitoring section)
- Remove duplicate "MCP Audit" from MCP Server sidebar group — it stays
  only in the Audit group under Monitoring
- Improve McpAuditTab: fetch /api/mcp/audit/stats and show 4-card stat bar
  (calls 24h, success rate, avg duration, top tool) above the filters
- Add audit-a2a to HIDEABLE_SIDEBAR_ITEM_IDS
- Add i18n keys: auditA2a in sidebar + header sections, a2a* in compliance namespace
2026-05-16 09:57:40 -03:00