{{ logsAutoRefreshInterval ? `Auto (${logsAutoRefreshInterval >= 60000 ? (logsAutoRefreshInterval/60000) + 'min' : (logsAutoRefreshInterval/1000) + 's'})` : 'Refresh' }} Refresh Sync OpenRouter Refresh

{{ currentSettingsService.label }}

Share live usage {{ getServiceActionLabel(currentSettingsService.id) }}
{{ getServiceActiveConfigCount(currentSettingsService.id) }} / {{ getServiceConfigCount(currentSettingsService.id) }} enabled {{ formatNumber(currentSettingsRecentSummary.totalRequests || 0) }} requests 5m {{ getServiceOverviewRate(currentSettingsService.id) }} success {{ formatNumber(getServiceRoutingTotal(currentSettingsService.id)) }} routed
Disabled {{ getAuthTypeLabel(config.authType) }} w{{ getConfigStats(currentSettingsService.id, config.name)?.weight ?? config.weight }} · {{ calculateTrafficPercent(currentSettingsService.id, config.name) }}% Reserved · {{ config.allowedApiKeyIds.length }} {{ config.allowedApiKeyIds.length === 1 ? 'key' : 'keys' }} {{ getConfigIdentityHint(config, currentSettingsService.id) }}
Plan usage
No plan usage for this auth mode
Live 5m
{{ getWindowSummary(currentSettingsService.id, config.name, '5m').total_requests }} req {{ formatSummarySuccessRate(getWindowSummary(currentSettingsService.id, config.name, '5m')) }} ok {{ getWindowSummary(currentSettingsService.id, config.name, '5m').failure }} err {{ configLatencyText(currentSettingsService.id, config.name) }}
No requests in the last 5m
  • {{ group.model }} {{ describeFailureGroup(group).slice(group.model.length + 3) }} ×{{ group.count }}
  • +{{ configFailureGroups(currentSettingsService.id, config.name).length - 2 }} more
Models
{{ m }}
Any (general)
By model Calendar week / month (UTC) ?
ModelThis weekThis monthAt this pace
{{ model.model }} {{ model.week_requests.toLocaleString() }} req · {{ formatTokensK(model.week_tokens) }} tok {{ model.month_requests.toLocaleString() }} req · {{ formatTokensK(model.month_tokens) }} tok {{ modelRunwayText(model) }}
Protocol · Health · Diagnostics

Protocol / Upstream

Wire protocol and target host

Protocol {{ getConfigProtocolLabel(config, currentSettingsService.id) }}
Upstream {{ getConfigUpstream(config, currentSettingsService.id) }}

Health

Recent success ratio and activity

{{ getHealthPercent(getConfigStats(currentSettingsService.id, config.name)) }} OK {{ getConfigStats(currentSettingsService.id, config.name)?.total_success || 0 }}/{{ getConfigStats(currentSettingsService.id, config.name)?.total_requests || 0 }}
{{ getWindowSummary(currentSettingsService.id, config.name, '24h').total_requests }} / 24h {{ getConfigStats(currentSettingsService.id, config.name)?.last_updated ? formatLastUpdated(getConfigStats(currentSettingsService.id, config.name)?.last_updated) : 'No activity' }}
Req 24h {{ getWindowSummary(currentSettingsService.id, config.name, '24h').total_requests }}
OK Rate {{ formatSummarySuccessRate(getWindowSummary(currentSettingsService.id, config.name, '24h')) }}
Routed {{ getRoutingStats(currentSettingsService.id, config.name)?.count || 0 }}
Last {{ getLastResultLabel(currentSettingsService.id, config.name) }}

Request Volume

Last 24 hours by configuration

Latency

Recent and hourly distribution

Retired {{ retiredSettingsConfigs.length }} Kept on the books, not served, not sampled. Re-list one to bring it back (disabled).
  • {{ config.name }} {{ config.id }} {{ getAuthTypeLabel(config.authType) }} {{ getConfigIdentityHint(config, currentSettingsService.id) }} {{ getConfigModelList(config).join(', ') }}
    Re-list
{{ activePromptCount }} / {{ PROMPT_SERVICES.length }} services with prompts Applies to new requests

{{ activePromptService.label }} prompt

{{ activePromptService.description }} · {{ activePromptService.field }}

{{ !customPromptsLoaded ? 'Not loaded' : isCustomPromptDirty(selectedPromptService) ? 'Unsaved changes' : 'Saved' }}
Plain text · empty means no injected prompt{{ customPrompts[selectedPromptService].prompt.length.toLocaleString() }} characters
Clear draft
How prompt injection works

Prompts apply to all requests for the selected service. Claude uses the top-level system field; Codex uses instructions; Gemini and Grok use a system message. Draft changes do not affect traffic until published. Clearing the editor also requires publishing.

New Key
Key Status Requests Traffic Models Last Used
{{ keyEntry.name }} ID {{ (keyEntry.id || '').slice(0, 8) || '—' }} {{ keyEntry.active ? 'Active' : 'Disabled' }} {{ formatNumber(keyEntry.requestCount || 0) }} In {{ formatTokensK(keyEntry.inputTokens || 0) }} Out {{ formatTokensK(keyEntry.outputTokens || 0) }} Total {{ formatTokensK((keyEntry.inputTokens || 0) + (keyEntry.outputTokens || 0)) }} {{ formatAllowedModels(keyEntry) }} {{ keyEntry.lastUsedAt ? formatRelativeTime(keyEntry.lastUsedAt) : 'Never' }} Copy Edit

No Access Keys

Create your first access key to enable client authentication.

Create Key
All Models Select Models
{{ model }}
No models in Pricing yet
If not configured, this key can use every model.
All Sites Select Sites
A friendly name to identify this key
All Models (default) Select specific models
{{ model }}
No models in Pricing yet
Leave as All Models to avoid restrictions.
All Sites (default) Select specific sites
No sites configured yet

Key Created Successfully

Make sure to copy this key now. You won't be able to see it again!
{{ newlyCreatedKey.key }} Copy

Request History

{{ historyPagination.total }} logs
Prompts Success {{ historySummary.success }} Error {{ historySummary.failure }}
Service Session Model Route
{{ allLogsLoading ? 'Loading...' : 'No logs found' }}
{{ log.status_code || '—' }} {{ getLogServiceType(log) }} — {{ routedFromLabel(log) }}{{ log.model || '—' }} {{ log.thinking_level }} {{ log.channel || '—' }}{{ formatRouteTag(log.route_tag) }}
{{ formatRequestBodySize(log.original_body_length) }}
{{ log.duration_ms ? (log.duration_ms >= 1000 ? (log.duration_ms / 1000).toFixed(1) + 's' : log.duration_ms + 'ms') : '—' }} {{ timeAgo(log.timestamp) }}
⚠ {{ log.error_type }} {{ log.method }} {{ truncatePath(log.path) }} {{ log.agent || '—' }} {{ logTokenSummary(log) }} {{ logCostLabel(log) }} {{ log.api_key_name }} {{ log.client_ip }}
{{ log.user_message }}
Conversation · session_id

{{ selectedSessionId || '—' }}

{{ sessionSummaryLine }}
cwd {{ sessionCwd }}
session {{ sessionTrace.session_id || selectedSessionId }} · {{ sessionTrace.span_count || sessionTrace.total || 0 }} spans · {{ formatTokensK(sessionTrace.total_tokens || 0) }} tokens · {{ ((sessionTrace.total_duration_ms || 0) / 1000).toFixed(1) }}s · {{ (sessionTrace.models || []).join(', ') }}
Refresh Open full detail
{{ sessionTraceError }}
No session selected
{{ sessionSpanDetailError }}
Select a span

Overview metrics

Requests, tokens, estimated cost, and pricing coverage

Requests {{ formatNumber(insightsOverview?.totals?.requestCount || 0) }} successful
Tokens {{ formatTokensK(insightsOverview?.totals?.totalTokens || 0) }} {{ formatTokensK(insightsOverview?.totals?.inputTokens || 0) }} in · {{ formatTokensK(insightsOverview?.totals?.outputTokens || 0) }} out
Est. API Cost {{ formatCostUsd(insightsOverview?.totals?.costUsd || 0) }} {{ formatCostUsd(insightsOverview?.totals?.avgCostUsd || 0) }} / req · OpenRouter rates
$ / 1M Tokens {{ formatCostUsd(insightsOverview?.totals?.costPerMTokens || 0) }} blended · priced tokens only
Pricing Coverage {{ (insightsOverview?.totals?.pricingCoverage || 0).toFixed(1) }}% {{ insightsOverallModels.length }} models shown · unpriced excluded from rate
{{ insightsError }} · Showing last successful result.
Loading usage…
No usage data for this window.

Channel usage

Provider and model costs · OpenRouter rates

{{ formatTokensK(insightsOverview?.totals?.totalTokens || 0) }} · {{ formatCostUsd(insightsOverview?.totals?.costUsd || 0) }}
ProviderChannelsRequestsTokensCostCost share
ChannelWindow creditsPlan usage

Model ranking

Sorted by tokens · estimated from OpenRouter rates

# Model Requests Tokens Cost Cost share

Agent ranking

Sorted by tokens · estimated from OpenRouter rates

# Agent Requests Tokens Cost Cost share

Model metrics

Usage, estimated cost, and users for this model

{{ insightsError }} · Showing last successful result.
Loading model usage…

Agent share

Who calls this model
{{ formatNumber(insightsModelPageAgentDonut.total) }} Requests
{{ sl.label }} {{ Math.round(sl.pct * 100) }}%

Used by agents

Client agents calling this model
{{ insightsModelAgents.length }} agents
{{ item.value }} {{ formatTokensK(item.totalTokens) }}
{{ item.requestCount }} req {{ item.requestShare.toFixed(1) }}% {{ formatCostUsd(item.costUsd) }} last {{ item.lastSeen.replace('T', ' ').substring(0, 16) }}
No agent data

Used by keys

API keys calling this model
{{ insightsModelKeys.length }} keys
{{ item.value }} {{ formatTokensK(item.totalTokens) }}
{{ item.requestCount }} req {{ item.requestShare.toFixed(1) }}% {{ formatCostUsd(item.costUsd) }} last {{ item.lastSeen.replace('T', ' ').substring(0, 16) }}
No key data

Routing configs

Upstream config footprint for this model
{{ insightsModelConfigs.length }} configs
{{ item.value }} {{ item.requestCount }} req
{{ item.requestShare.toFixed(1) }}% {{ formatTokensK(item.totalTokens) }} {{ formatCostUsd(item.costUsd) }}
No usage data for this model and window.

Agent metrics

Usage, estimated cost, and coverage for this agent

{{ insightsError }} · Showing last successful result.
Loading agent usage…

Model share

Token distribution for this agent
{{ formatTokensK(insightsAgentPageModelDonut.total) }} Tokens
{{ sl.label }} {{ Math.round(sl.pct * 100) }}%

Models used

Which models this agent requests
{{ insightsAgentModels.length }} models
{{ item.value }} {{ item.costUsd ? formatCostUsd(item.costUsd) : formatTokensK(item.totalTokens) }}
{{ item.requestCount }} req {{ item.requestShare.toFixed(1) }}% {{ formatTokensK(item.totalTokens) }}

Keys used

Which API keys this agent uses
{{ insightsAgentKeys.length }} keys
{{ item.value }} {{ formatTokensK(item.totalTokens) }}
{{ item.requestCount }} req {{ item.requestShare.toFixed(1) }}% {{ formatCostUsd(item.costUsd) }} last {{ item.lastSeen.replace('T', ' ').substring(0, 16) }}

Key activity

Hourly request heatmap per key
{{ entry.key }}
{{ insightsAgentKeyActivity[0].buckets[0].bucket.replace('T', ' ') }} {{ insightsAgentKeyActivity[0].buckets[insightsAgentKeyActivity[0].buckets.length - 1].bucket.replace('T', ' ') }}
No usage data for this agent and window.
{{ selectedLog.status_code || '---' }}
{{ selectedLog.service }} · {{ formatChannelName(selectedLog.channel) }} {{ selectedLog.route_tag }} {{ routedFromLabel(selectedLog) }} → {{ selectedLog.model }} · {{ selectedLog.model }} · effort {{ selectedLog.thinking_level }} · {{ selectedLog.duration_ms }}ms · {{ selectedLog.timestamp }}
Session {{ String(selectedLog.session_id).slice(0, 8) }} {{ shareUrl ? 'Copied!' : '🔗 Share' }}
Routing trigger: {{ selectedLog.route_reason }}
💬 User Message
{{ userMessageText }}
Client → Proxy {{ selectedLog.status_code }}
Host: 127.0.0.1:3211
Path: {{ selectedLog.path }}
Proxy → Upstream {{ selectedLog.status_code }} N/A
Host: {{ getUpstreamHost(selectedLog.target_url) }}
Path: {{ getUpstreamPath(selectedLog.target_url) }}
Not forwarded
Request
{{ selectedLog.method }} {{ selectedLog.path }} Copy
Client: {{ selectedLog.client_ip }} ID: {{ selectedLog.request_id }}
Headers ({{ Object.keys(selectedLog.original_headers || {}).length }}) Copy
No headers
{{ key }} {{ formatHeaderDisplayValue(key, selectedLog.original_headers[key]) }}
Body ({{ formatBytes(selectedLog.original_body_length) }}) Truncated Copy Format
No body
Response {{ selectedLog.status_code }}
Status: {{ selectedLog.status_code }} {{ getStatusText(selectedLog.status_code) }} Size: {{ formatBytes(selectedLog.response_bytes) }} Duration: {{ selectedLog.duration_ms }}ms
Headers ({{ Object.keys(selectedLog.response_headers || {}).length }}) Copy
No headers
{{ key }} {{ formatHeaderDisplayValue(key, selectedLog.response_headers[key]) }}
Body ({{ formatBytes(selectedLog.response_content_length) }}) Truncated Copy {{ isResponseContentParsed ? 'Raw' : 'Parse' }} Format
No response
Request was not forwarded to upstream

Realtime requests

Claude is connected Claude is not connected Codex is connected Codex not connected
connect disconnect
No real-time request yet
Serve path state time consuming operate
{{ request.service }}{{ request.channel ? ` [${request.channel}]` : '' }} {{ request.path }} {{ getStatusDisplay(request.status).text }} {{ request.displayDuration }}ms Details

Request history

Total {{ (historyPagination && historyPagination.total) || 0 }} logs (current page {{ filteredLogs.length }} logs, total {{ (historyPagination && historyPagination.overallTotal) || 0 }} logs, keep the most recent {{ systemConfig.logLimit }} logs)
Success {{ historySummary.success }} Error {{ historySummary.failure }}
refresh
time Serve URL state time consuming Usage operate
{{ allLogsLoading ? 'Loading log data...' : ((allLogs.items && allLogs.items.length === 0) ? 'No log data' : 'No matching log') }}
{{ formatTimestamp(log.timestamp) }} {{ formatServiceWithChannel(log.service, log.channel) }} {{ formatMethodWithURL(log.method, log.path) }} {{ log.status_code || '-' }} FO {{ log.duration_ms ? `${log.duration_ms}ms` : '-' }} {{ formatUsageSummary(log.usage, log.service) }} Details
{{ selectedRealtimeRequest.request_id }} {{ selectedRealtimeRequest.service }} {{ selectedRealtimeRequest.channel }} {{ getStatusDisplay(selectedRealtimeRequest.status).text }} {{ selectedRealtimeRequest.method }} {{ selectedRealtimeRequest.path }} {{ selectedRealtimeRequest.displayDuration }}ms {{ selectedRealtimeRequest.status_code }} {{ formatRealtimeTime(selectedRealtimeRequest.start_time) }} {{ selectedRealtimeRequest.target_url }}

real-time response streaming

{{ selectedRealtimeRequest.responseText }}
No response data yet...

Request header

{{ stringifyHeadersForDisplay(selectedRealtimeRequest.request_headers) }}
{{ healthCounts[id] || 0 }} {{ meta.label.toLowerCase() }}
{{ healthState.error ? 'Upstream health is unavailable right now.' : 'No requests in this window.' }}

Proxy transitions in window

{{ healthEvents.length }} lines from server_log · also drawn as markers
  1. {{ e.kind_label }} {{ e.message }}
{{ routingSaveNote }} ⌘S
{{ pricingSyncSummary.matched }}/{{ pricingSyncSummary.total }} matched Quota and Kiro multipliers are manual overrides
Pricing and quota calculation

Models are discovered from configured services; USD prices sync from OpenRouter. API-key quotas use raw total tokens × quota multiplier. Raw token counts are recorded separately.

refreshed {{ serverLogsRelative(serverLogsFetchedAt) }}

Server log mirror is not available

{{ serverLogsUnavailable }} · the per-slot file ~/.evot/run/unified_proxy-<port>.log remains the authority.

Request

{{ serverLogsTrace.request_id }}

copy id open in Logs close

Hops request history

No request-history row yet — the request failed before it was recorded, or the row is still on its way.

  1. {{ h.hop }} {{ h.status_code || '—' }} {{ h.service }} / {{ h.config_name }} {{ h.model }}

Log lines {{ serverLogsTrace.lines.length }}, oldest first

  1. {{ serverLogsClock(l.ts) }} {{ l.level.toLowerCase() }} {{ serverLogsHead(l.message) }} — {{ l.logger }}
Loading…