diff --git a/plugins/OpenRouter/v1/configValidation.json b/plugins/OpenRouter/v1/configValidation.json new file mode 100644 index 00000000..f24b2554 --- /dev/null +++ b/plugins/OpenRouter/v1/configValidation.json @@ -0,0 +1,22 @@ +{ + "steps": [ + { + "displayName": "Authenticate", + "dataStream": { + "name": "credits" + }, + "required": true, + "success": "Connected to OpenRouter.", + "error": "Could not authenticate. Check that the key is valid, enabled, and has not expired." + }, + { + "displayName": "Check management access", + "dataStream": { + "name": "workspaces" + }, + "required": false, + "success": "Management key detected. All data streams are available.", + "error": "Could not read workspaces. Workspaces, API keys, usage, and performance need a management key; everything else still works." + } + ] +} diff --git a/plugins/OpenRouter/v1/custom_types.json b/plugins/OpenRouter/v1/custom_types.json new file mode 100644 index 00000000..71d74943 --- /dev/null +++ b/plugins/OpenRouter/v1/custom_types.json @@ -0,0 +1,30 @@ +[ + { + "name": "Model", + "sourceType": "Model", + "icon": "brain", + "singular": "Model", + "plural": "Models" + }, + { + "name": "Provider", + "sourceType": "Provider", + "icon": "server", + "singular": "Provider", + "plural": "Providers" + }, + { + "name": "Workspace", + "sourceType": "Workspace", + "icon": "layer-group", + "singular": "Workspace", + "plural": "Workspaces" + }, + { + "name": "API Key", + "sourceType": "API Key", + "icon": "key", + "singular": "API Key", + "plural": "API Keys" + } +] diff --git a/plugins/OpenRouter/v1/dataStreams/apiKeys.json b/plugins/OpenRouter/v1/dataStreams/apiKeys.json new file mode 100644 index 00000000..16429c04 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/apiKeys.json @@ -0,0 +1,105 @@ +{ + "name": "apiKeys", + "displayName": "API Keys", + "description": "API keys in a workspace, with spend and limits in USD (requires a management key)", + "tags": ["API Keys", "Cost"], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "keys", + "paging": { + "mode": "offset", + "offset": { + "mode": "row", + "rowCountIn": { "realm": "payloadArraySize", "path": "data" }, + "base": 0 + }, + "out": { "realm": "queryArg", "path": "offset" } + }, + "getArgs": [ + { "key": "workspace_id", "value": "{{object.rawId}}" }, + { "key": "include_disabled", "value": "true" } + ], + "headers": [], + "pathToData": "data" + }, + "matches": { + "sourceType": { "type": "oneOf", "values": ["Workspace"] } + }, + "metadata": [ + { + "name": "hash", + "displayName": "Key Hash", + "shape": "string" + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "disabled", + "displayName": "Disabled", + "shape": "boolean" + }, + { + "name": "usage_daily", + "displayName": "Spend Today", + "shape": "usd" + }, + { + "name": "usage_weekly", + "displayName": "Spend This Week", + "shape": "usd" + }, + { + "name": "usage_monthly", + "displayName": "Spend This Month", + "shape": "usd" + }, + { + "name": "usage", + "displayName": "Total Spend", + "shape": "usd" + }, + { + "name": "limit", + "displayName": "Limit", + "shape": "usd" + }, + { + "name": "limit_remaining", + "displayName": "Limit Remaining", + "shape": "usd" + }, + { + "name": "limitUsed", + "displayName": "Limit Used (%)", + "shape": ["number", { "decimalPlaces": 1 }], + "computed": true, + "valueExpression": "{{ $['limit'] > 0 && $['limit_remaining'] != null ? Math.min(100, 100 * ($['limit'] - $['limit_remaining']) / $['limit']) : null }}" + }, + { + "name": "limit_reset", + "displayName": "Limit Reset", + "shape": "string" + }, + { + "name": "workspace_id", + "displayName": "Workspace ID", + "shape": "string" + }, + { + "name": "created_at", + "displayName": "Created", + "shape": "date" + }, + { + "name": "expires_at", + "displayName": "Expires", + "shape": "date" + } + ], + "timeframes": false +} diff --git a/plugins/OpenRouter/v1/dataStreams/appRankings.json b/plugins/OpenRouter/v1/dataStreams/appRankings.json new file mode 100644 index 00000000..15c4a75b --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/appRankings.json @@ -0,0 +1,239 @@ +{ + "name": "appRankings", + "displayName": "App Rankings", + "description": "Top public apps on OpenRouter by tokens processed, most popular or trending (from OpenRouter's public apps marketplace)", + "tags": [ + "Usage" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "datasets/app-rankings", + "paging": { + "mode": "none" + }, + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0, 10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0, 10)}}" + }, + { + "key": "sort", + "value": "{{ typeof rankBy !== 'undefined' && rankBy ? rankBy : 'popular' }}" + }, + { + "key": "category", + "value": "{{ typeof category === 'string' && ['coding', 'creative', 'productivity', 'entertainment'].includes(category) ? category : null }}" + }, + { + "key": "subcategory", + "value": "{{ typeof category === 'string' && category && !['coding', 'creative', 'productivity', 'entertainment'].includes(category) ? category : null }}" + }, + { + "key": "limit", + "value": "100" + } + ], + "headers": [], + "postRequestScript": "appRankings.js" + }, + "matches": "none", + "metadata": [ + { + "name": "rank", + "displayName": "Rank", + "shape": "number" + }, + { + "name": "app_id", + "displayName": "App ID", + "shape": "string", + "visible": false + }, + { + "name": "app_name", + "displayName": "App", + "shape": "string", + "role": "label" + }, + { + "name": "total_tokens", + "displayName": "Total Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ], + "role": "value" + }, + { + "name": "total_requests", + "displayName": "Total Requests", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "name": "asOf", + "displayName": "As Of", + "shape": "date", + "visible": false + }, + { + "name": "citation", + "displayName": "Citation", + "shape": "string", + "visible": false + } + ], + "timeframes": [ + "last7days", + "last30days", + "thisMonth", + "lastMonth", + "thisQuarter", + "lastQuarter", + "thisYear", + "lastYear" + ], + "options": { + "minimumRequestIntervalSeconds": 86400 + }, + "ui": [ + { + "type": "choiceChips", + "name": "rankBy", + "label": "Rank by", + "defaultValue": "popular", + "options": [ + { + "value": "popular", + "label": "Most tokens" + }, + { + "value": "trending", + "label": "Trending" + } + ], + "help": "**Trending** ranks apps by token growth over the previous three periods of the same length, so it may return fewer apps" + }, + { + "type": "autocomplete", + "name": "category", + "label": "Category", + "isMulti": false, + "isClearable": true, + "data": { + "source": "fixed", + "values": [ + { + "label": "Coding", + "options": [ + { + "value": "coding", + "label": "All coding" + }, + { + "value": "cli-agent", + "label": "CLI agents" + }, + { + "value": "ide-extension", + "label": "IDE extensions" + }, + { + "value": "cloud-agent", + "label": "Cloud agents" + }, + { + "value": "programming-app", + "label": "Programming apps" + }, + { + "value": "native-app-builder", + "label": "Native app builders" + } + ] + }, + { + "label": "Creative", + "options": [ + { + "value": "creative", + "label": "All creative" + }, + { + "value": "creative-writing", + "label": "Creative writing" + }, + { + "value": "video-gen", + "label": "Video generation" + }, + { + "value": "image-gen", + "label": "Image generation" + }, + { + "value": "audio-gen", + "label": "Audio generation" + } + ] + }, + { + "label": "Productivity", + "options": [ + { + "value": "productivity", + "label": "All productivity" + }, + { + "value": "writing-assistant", + "label": "Writing assistants" + }, + { + "value": "general-chat", + "label": "General chat" + }, + { + "value": "personal-agent", + "label": "Personal agents" + }, + { + "value": "legal", + "label": "Legal" + } + ] + }, + { + "label": "Entertainment", + "options": [ + { + "value": "entertainment", + "label": "All entertainment" + }, + { + "value": "roleplay", + "label": "Roleplay" + }, + { + "value": "game", + "label": "Games" + } + ] + } + ] + } + } + ] +} diff --git a/plugins/OpenRouter/v1/dataStreams/benchmarks.json b/plugins/OpenRouter/v1/dataStreams/benchmarks.json new file mode 100644 index 00000000..71575f96 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/benchmarks.json @@ -0,0 +1,131 @@ +{ + "name": "benchmarks", + "displayName": "Benchmarks", + "description": "Model benchmark scores from Artificial Analysis, Design Arena, and OpenRouter evals (refreshed daily)", + "tags": [ + "Models", + "Benchmarks" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "benchmarks", + "paging": { + "mode": "none" + }, + "getArgs": [ + { + "key": "source", + "value": "{{source || null}}" + } + ], + "headers": [], + "postRequestScript": "benchmarks.js" + }, + "matches": "none", + "ui": [ + { + "type": "autocomplete", + "name": "source", + "label": "Source", + "isMulti": false, + "isClearable": true, + "data": { + "source": "fixed", + "values": [ + { + "value": "artificial-analysis", + "label": "Artificial Analysis" + }, + { + "value": "design-arena", + "label": "Design Arena" + }, + { + "value": "openrouter", + "label": "OpenRouter evals" + } + ] + } + } + ], + "metadata": [ + { + "name": "model", + "displayName": "Model", + "shape": "string" + }, + { + "name": "modelName", + "displayName": "Model Name", + "shape": "string", + "role": "label" + }, + { + "name": "source", + "displayName": "Source", + "shape": "string" + }, + { + "name": "benchmark", + "displayName": "Benchmark", + "shape": "string" + }, + { + "name": "metric", + "displayName": "Metric", + "shape": "string" + }, + { + "name": "score", + "displayName": "Score", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "name": "winRate", + "displayName": "Win Rate", + "shape": "percent" + }, + { + "name": "tasks", + "displayName": "Tasks", + "shape": "number" + }, + { + "name": "avgCostPerTask", + "displayName": "Avg Cost per Task", + "shape": "usd" + }, + { + "name": "avgDurationMs", + "displayName": "Avg Duration", + "shape": "milliseconds" + }, + { + "name": "lastRun", + "displayName": "Last Run", + "shape": "date" + }, + { + "name": "asOf", + "displayName": "As Of", + "shape": "date", + "visible": false + }, + { + "name": "citation", + "displayName": "Citation", + "shape": "string", + "visible": false + } + ], + "options": { + "minimumRequestIntervalSeconds": 86400 + }, + "timeframes": false +} diff --git a/plugins/OpenRouter/v1/dataStreams/credits.json b/plugins/OpenRouter/v1/dataStreams/credits.json new file mode 100644 index 00000000..26debe83 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/credits.json @@ -0,0 +1,38 @@ +{ + "name": "credits", + "displayName": "Credits", + "description": "Credits purchased, used, and remaining for the account (USD)", + "tags": ["Cost", "Billing"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "credits", + "paging": { + "mode": "none" + }, + "getArgs": [], + "headers": [], + "pathToData": "data" + }, + "matches": "none", + "metadata": [ + { + "name": "total_credits", + "displayName": "Total Credits", + "shape": "usd" + }, + { + "name": "total_usage", + "displayName": "Total Usage", + "shape": "usd" + }, + { + "name": "remaining", + "displayName": "Remaining", + "shape": "usd", + "computed": true, + "valueExpression": "{{ $['total_credits'] - $['total_usage'] }}" + } + ], + "timeframes": false +} diff --git a/plugins/OpenRouter/v1/dataStreams/modelProviders.json b/plugins/OpenRouter/v1/dataStreams/modelProviders.json new file mode 100644 index 00000000..08a4d91d --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/modelProviders.json @@ -0,0 +1,191 @@ +{ + "name": "modelProviders", + "displayName": "Model Providers", + "description": "Providers serving a model, with status, price, uptime, latency, and throughput (last 5 minutes to 1 day)", + "tags": [ + "Models", + "Performance" + ], + "baseDataSourceName": "httpRequestScopedSingle", + "config": { + "httpMethod": "get", + "endpointPath": "models/{{object.rawId}}/endpoints", + "paging": { + "mode": "none" + }, + "getArgs": [], + "headers": [], + "pathToData": "data.endpoints", + "expandInnerObjects": true + }, + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model" + ] + } + }, + "metadata": [ + { + "name": "model_name", + "displayName": "Model", + "shape": "string" + }, + { + "name": "provider_name", + "displayName": "Provider", + "shape": "string", + "role": "label" + }, + { + "name": "status", + "visible": false, + "displayName": "Status Code", + "shape": "number" + }, + { + "name": "health", + "displayName": "Status", + "shape": "state", + "computed": true, + "valueExpression": "{{ (s => s == null || s === '' ? 'unknown' : (n => n === 0 ? 'success' : n >= -3 ? 'warning' : 'error')(Number(s)))($['status']) }}" + }, + { + "name": "tag", + "displayName": "Tag", + "shape": "string" + }, + { + "name": "quantization", + "displayName": "Quantization", + "shape": "string" + }, + { + "name": "context_length", + "displayName": "Context Length", + "shape": "number" + }, + { + "name": "pricing.prompt", + "visible": false, + "displayName": "Input Price (per Token)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 8 + } + ] + }, + { + "name": "inputPrice", + "displayName": "Input Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ], + "computed": true, + "valueExpression": "{{ (v => v == null || v === '' || Number(v) < 0 ? null : Number(v) * 1e6)($['pricing.prompt']) }}" + }, + { + "name": "pricing.completion", + "visible": false, + "displayName": "Output Price (per Token)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 8 + } + ] + }, + { + "name": "outputPrice", + "displayName": "Output Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ], + "computed": true, + "valueExpression": "{{ (v => v == null || v === '' || Number(v) < 0 ? null : Number(v) * 1e6)($['pricing.completion']) }}" + }, + { + "name": "pricing.input_cache_read", + "visible": false, + "displayName": "Cache Read Price (per Token)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 8 + } + ] + }, + { + "name": "cacheReadPrice", + "displayName": "Cache Read Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ], + "computed": true, + "valueExpression": "{{ (v => v == null || v === '' || Number(v) < 0 ? null : Number(v) * 1e6)($['pricing.input_cache_read']) }}" + }, + { + "name": "uptime_last_5m", + "displayName": "Uptime (5m)", + "shape": "percent" + }, + { + "name": "uptime_last_30m", + "displayName": "Uptime (30m)", + "shape": "percent" + }, + { + "name": "uptime_last_1d", + "displayName": "Uptime (1d)", + "shape": "percent" + }, + { + "name": "latency_last_30m.p50", + "displayName": "Latency p50", + "shape": "milliseconds" + }, + { + "name": "latency_last_30m.p75", + "displayName": "Latency p75", + "shape": "milliseconds" + }, + { + "name": "latency_last_30m.p90", + "displayName": "Latency p90", + "shape": "milliseconds" + }, + { + "name": "latency_last_30m.p99", + "displayName": "Latency p99", + "shape": "milliseconds" + }, + { + "name": "throughput_last_30m.p50", + "displayName": "Throughput p50 (Tokens/s)", + "shape": [ + "number", + { + "decimalPlaces": 1 + } + ] + } + ], + "timeframes": false +} diff --git a/plugins/OpenRouter/v1/dataStreams/models.json b/plugins/OpenRouter/v1/dataStreams/models.json new file mode 100644 index 00000000..38b87b46 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/models.json @@ -0,0 +1,266 @@ +{ + "name": "models", + "displayName": "Models", + "description": "Models available through OpenRouter, with pricing, context length, and benchmark scores", + "tags": [ + "Models" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "models", + "paging": { + "mode": "none" + }, + "getArgs": [ + { + "key": "output_modalities", + "value": "all" + } + ], + "headers": [], + "expandInnerObjects": true, + "postRequestScript": "models.js" + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "Model ID", + "shape": "string" + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "author", + "displayName": "Author", + "shape": "string", + "computed": true, + "valueExpression": "{{ $['id'].split('/')[0] }}" + }, + { + "name": "canonical_slug", + "displayName": "Canonical Slug", + "shape": "string" + }, + { + "name": "permaslug", + "displayName": "Permaslug", + "shape": "string", + "computed": true, + "valueExpression": "{{ ($['canonical_slug'] || $['id'].replace(/:free$/, '')) + ($['id'].endsWith(':free') ? ':free' : '') }}" + }, + { + "name": "context_length", + "displayName": "Context Length", + "shape": "number" + }, + { + "name": "inputPrice", + "displayName": "Input Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ], + "computed": true, + "valueExpression": "{{ (v => v == null || v === '' || Number(v) < 0 ? null : Number(v) * 1e6)($['pricing.prompt']) }}" + }, + { + "name": "outputPrice", + "displayName": "Output Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ], + "computed": true, + "valueExpression": "{{ (v => v == null || v === '' || Number(v) < 0 ? null : Number(v) * 1e6)($['pricing.completion']) }}" + }, + { + "name": "cacheReadPrice", + "displayName": "Cache Read Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ], + "computed": true, + "valueExpression": "{{ (v => v == null || v === '' || Number(v) < 0 ? null : Number(v) * 1e6)($['pricing.input_cache_read']) }}" + }, + { + "name": "inputAffordability", + "displayName": "Input Affordability", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "outputAffordability", + "displayName": "Output Affordability", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "cacheReadAffordability", + "displayName": "Cache Read Affordability", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "top_provider.max_completion_tokens", + "displayName": "Max Completion Tokens", + "shape": "number" + }, + { + "name": "inputModalities", + "displayName": "Input Modalities", + "shape": "string", + "computed": true, + "valueExpression": "{{ JSON.parse($['architecture.input_modalities'] || '[]').join(', ') }}" + }, + { + "name": "outputModalities", + "displayName": "Output Modalities", + "shape": "string", + "computed": true, + "valueExpression": "{{ JSON.parse($['architecture.output_modalities'] || '[]').join(', ') }}" + }, + { + "name": "benchmarks.artificial_analysis.intelligence_index", + "displayName": "Intelligence Index", + "shape": "number" + }, + { + "name": "benchmarks.artificial_analysis.coding_index", + "displayName": "Coding Index", + "shape": "number" + }, + { + "name": "benchmarks.artificial_analysis.agentic_index", + "displayName": "Agentic Index", + "shape": "number" + }, + { + "name": "knowledge_cutoff", + "displayName": "Knowledge Cutoff", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ] + }, + { + "name": "created", + "displayName": "Created", + "shape": [ + "date", + { + "inputPattern": "t" + } + ] + }, + { + "name": "expiration_date", + "displayName": "Expiration Date", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ] + }, + { + "name": "pricing.prompt", + "visible": false, + "displayName": "Input Price (per Token)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 8 + } + ] + }, + { + "name": "pricing.completion", + "visible": false, + "displayName": "Output Price (per Token)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 8 + } + ] + }, + { + "name": "pricing.input_cache_read", + "visible": false, + "displayName": "Cache Read Price (per Token)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 8 + } + ] + }, + { + "name": "architecture.input_modalities", + "visible": false + }, + { + "name": "architecture.output_modalities", + "visible": false + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "models", + "label": "Model(s)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model" + ] + } + } + }, + { + "type": "number", + "name": "affordabilityCeiling", + "label": "Affordability ceiling ($/1M tokens)", + "help": "Sets the price that scores 0 on the affordability columns. Prices score on a log scale, from 100 at $0.01 per 1M tokens down to 0 at this price.", + "defaultValue": 1000, + "validation": { + "min": 1 + } + } + ] +} diff --git a/plugins/OpenRouter/v1/dataStreams/performance.json b/plugins/OpenRouter/v1/dataStreams/performance.json new file mode 100644 index 00000000..baa9498e --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/performance.json @@ -0,0 +1,161 @@ +{ + "name": "performance", + "displayName": "Performance", + "description": "Latency, time to first token, and throughput percentiles over time, optionally grouped by model, provider, workspace, API key, or app (last 30 days at most; requires a management key)", + "tags": [ + "Usage", + "Performance" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "post", + "endpointPath": "analytics/query", + "paging": { + "mode": "none" + }, + "getArgs": [], + "headers": [], + "postBody": "{{ (() => { const iso = (d) => new Date(d).toISOString().slice(0, 19) + 'Z'; const days = (new Date(timeframe.end) - new Date(timeframe.start)) / 864e5; const granularity = days <= 2 ? 'hour' : days <= 31 ? 'day' : days <= 92 ? 'week' : 'month'; const selected = typeof filterObjects !== 'undefined' && Array.isArray(filterObjects) ? filterObjects : []; const one = (v) => (Array.isArray(v) ? v[0] : v); const idsOf = (type, ...props) => [...new Set(selected.filter((o) => one(o.sourceType) === type).flatMap((o) => props.map((p) => one(o[p]))).filter(Boolean))]; const rules = [ ['model', idsOf('Model', 'rawId', 'canonical_slug')], ['provider', idsOf('Provider', 'name')], ['workspace', idsOf('Workspace', 'rawId')], ['api_key_id', idsOf('API Key', 'rawId')] ]; const filters = rules.filter(([, values]) => values.length).map(([field, value]) => ({ field, operator: 'in', value })); return JSON.stringify({ metrics: ['p50_latency', 'p90_latency', 'p50_total_time_to_first_token', 'p90_total_time_to_first_token', 'p50_throughput'], dimensions: typeof groupBy !== 'undefined' && groupBy ? [groupBy] : [], filters, granularity, time_range: { start: iso(timeframe.start), end: iso(timeframe.end) } }); })() }}", + "postRequestScript": "usage.js" + }, + "matches": "none", + "ui": [ + { + "type": "autocomplete", + "name": "groupBy", + "label": "Group by", + "help": "Select a dimension, or enter any dimension from [OpenRouter's analytics dimensions](https://openrouter.ai/docs/api/api-reference/analytics/get-available-analytics-metrics-and-dimensions).", + "allowCustomValues": true, + "isMulti": false, + "isClearable": true, + "data": { + "source": "fixed", + "values": [ + { + "value": "model", + "label": "Model" + }, + { + "value": "workspace", + "label": "Workspace" + }, + { + "value": "api_key_id", + "label": "API key" + }, + { + "value": "app", + "label": "App" + }, + { + "value": "user", + "label": "User" + }, + { + "value": "provider", + "label": "Provider" + }, + { + "value": "origin", + "label": "Origin" + }, + { + "value": "country", + "label": "Country" + }, + { + "value": "finish_reason", + "label": "Finish reason" + }, + { + "value": "streamed", + "label": "Streamed" + } + ] + } + }, + { + "type": "objects", + "name": "filterObjects", + "label": "Filter to objects (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model", + "Provider", + "Workspace", + "API Key" + ] + } + } + } + ], + "metadata": [ + { + "name": "date", + "displayName": "Date", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "role": "timestamp" + }, + { + "name": "group", + "displayName": "Group", + "shape": "string", + "role": "label" + }, + { + "name": "p50_latency", + "displayName": "Latency p50", + "shape": "milliseconds", + "role": "value" + }, + { + "name": "p90_latency", + "displayName": "Latency p90", + "shape": "milliseconds" + }, + { + "name": "p50_total_time_to_first_token", + "displayName": "Time To First Token p50", + "shape": "milliseconds" + }, + { + "name": "p90_total_time_to_first_token", + "displayName": "Time To First Token p90", + "shape": "milliseconds" + }, + { + "name": "p50_throughput", + "displayName": "Throughput p50 (Tokens/s)", + "shape": [ + "number", + { + "decimalPlaces": 1 + } + ] + } + ], + "timeframes": [ + "last12hours", + "last24hours", + "last7days", + "last30days", + "thisMonth" + ], + "defaultShaping": { + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + } + } +} diff --git a/plugins/OpenRouter/v1/dataStreams/providers.json b/plugins/OpenRouter/v1/dataStreams/providers.json new file mode 100644 index 00000000..06a1a350 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/providers.json @@ -0,0 +1,74 @@ +{ + "name": "providers", + "displayName": "Providers", + "description": "Providers serving models on OpenRouter, with headquarters, datacenter locations, and policy links", + "tags": [ + "Providers" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "providers", + "paging": { + "mode": "none" + }, + "getArgs": [], + "headers": [], + "postRequestScript": "providers.js" + }, + "matches": "none", + "metadata": [ + { + "name": "slug", + "displayName": "Provider ID", + "shape": "string" + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "headquarters", + "displayName": "Headquarters", + "shape": "string" + }, + { + "name": "datacenters", + "displayName": "Datacenters", + "shape": "string" + }, + { + "name": "status_page_url", + "displayName": "Status Page", + "shape": [ + "url", + { + "label": "Status page" + } + ] + }, + { + "name": "privacy_policy_url", + "displayName": "Privacy Policy", + "shape": [ + "url", + { + "label": "Privacy policy" + } + ] + }, + { + "name": "terms_of_service_url", + "displayName": "Terms Of Service", + "shape": [ + "url", + { + "label": "Terms of service" + } + ] + } + ], + "timeframes": false +} diff --git a/plugins/OpenRouter/v1/dataStreams/rankings.json b/plugins/OpenRouter/v1/dataStreams/rankings.json new file mode 100644 index 00000000..30269124 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/rankings.json @@ -0,0 +1,269 @@ +{ + "name": "rankings", + "displayName": "Model Rankings", + "description": "Top models by tokens processed across all OpenRouter traffic (daily, from OpenRouter's public rankings dataset)", + "tags": [ + "Models", + "Usage" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "datasets/rankings-daily", + "paging": { + "mode": "none" + }, + "getArgs": [ + { + "key": "start_date", + "value": "{{timeframe.start.substring(0, 10)}}" + }, + { + "key": "end_date", + "value": "{{timeframe.end.substring(0, 10)}}" + }, + { + "key": "period", + "value": "{{ typeof segment === 'string' && /^(category|language):/.test(segment) && (typeof period !== 'string' || !period || period === 'day') ? 'week' : typeof period === 'string' && period ? period : null }}" + }, + { + "key": "category", + "value": "{{ typeof segment === 'string' && segment.startsWith('category:') ? segment.slice(9) : null }}" + }, + { + "key": "language_type", + "value": "{{ typeof segment === 'string' && segment.startsWith('language:') ? segment.slice(9) : null }}" + }, + { + "key": "modality", + "value": "{{ typeof segment === 'string' && segment.startsWith('modality:') ? segment.slice(9) : null }}" + }, + { + "key": "context_bucket", + "value": "{{ typeof segment === 'string' && segment.startsWith('context:') ? segment.slice(8) : null }}" + } + ], + "headers": [], + "postRequestScript": "rankings.js" + }, + "matches": "none", + "ui": [ + { + "type": "choiceChips", + "name": "period", + "label": "Period", + "defaultValue": "day", + "options": [ + { + "value": "day", + "label": "Day" + }, + { + "value": "week", + "label": "Week" + }, + { + "value": "month", + "label": "Month" + } + ] + }, + { + "type": "autocomplete", + "name": "segment", + "label": "Segment (optional)", + "isMulti": false, + "isClearable": true, + "help": "Shows weekly estimates for **Use case** and **Language** segments, so a **Day** period is shown weekly", + "data": { + "source": "fixed", + "values": [ + { + "label": "Use case (estimated)", + "options": [ + { + "value": "category:programming", + "label": "Programming" + }, + { + "value": "category:roleplay", + "label": "Roleplay" + }, + { + "value": "category:marketing", + "label": "Marketing" + }, + { + "value": "category:marketing/seo", + "label": "Marketing / SEO" + }, + { + "value": "category:technology", + "label": "Technology" + }, + { + "value": "category:science", + "label": "Science" + }, + { + "value": "category:translation", + "label": "Translation" + }, + { + "value": "category:legal", + "label": "Legal" + }, + { + "value": "category:finance", + "label": "Finance" + }, + { + "value": "category:health", + "label": "Health" + }, + { + "value": "category:trivia", + "label": "Trivia" + }, + { + "value": "category:academia", + "label": "Academia" + } + ] + }, + { + "label": "Language (estimated)", + "options": [ + { + "value": "language:natural", + "label": "Natural language" + }, + { + "value": "language:programming", + "label": "Programming languages" + } + ] + }, + { + "label": "Modality", + "options": [ + { + "value": "modality:text", + "label": "Text output" + }, + { + "value": "modality:image_output", + "label": "Image output" + }, + { + "value": "modality:image", + "label": "Image input" + }, + { + "value": "modality:audio", + "label": "Audio input" + }, + { + "value": "modality:tool_calling", + "label": "Tool calling" + } + ] + }, + { + "label": "Context length", + "options": [ + { + "value": "context:1K", + "label": "1K tokens" + }, + { + "value": "context:10K", + "label": "10K tokens" + }, + { + "value": "context:100K", + "label": "100K tokens" + }, + { + "value": "context:1M", + "label": "1M tokens" + }, + { + "value": "context:10M", + "label": "10M tokens" + } + ] + } + ] + } + }, + { + "type": "number", + "name": "top", + "label": "Top models per period (optional)", + "help": "Keep the models with the most tokens in each period and combine the rest into **Other**" + } + ], + "metadata": [ + { + "name": "date", + "displayName": "Date", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "role": "timestamp" + }, + { + "name": "model_permaslug", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "author", + "displayName": "Author", + "shape": "string", + "computed": true, + "valueExpression": "{{ $['model_permaslug']?.split('/')[0] }}" + }, + { + "name": "total_tokens", + "displayName": "Total Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "name": "asOf", + "displayName": "As Of", + "shape": "date", + "visible": false + }, + { + "name": "citation", + "displayName": "Citation", + "shape": "string", + "visible": false + } + ], + "timeframes": [ + "last7days", + "last30days", + "thisMonth", + "lastMonth", + "thisQuarter", + "lastQuarter", + "thisYear", + "lastYear" + ], + "options": { + "minimumRequestIntervalSeconds": 86400 + } +} diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/appRankings.js b/plugins/OpenRouter/v1/dataStreams/scripts/appRankings.js new file mode 100644 index 00000000..b64d3380 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/appRankings.js @@ -0,0 +1,6 @@ +// Adds the as-of date and citation OpenRouter requires to every row, and +// converts total_tokens (sent as a decimal string) to a number +const asOf = data?.meta?.as_of; +const citation = `Source: OpenRouter (openrouter.ai/apps), as of ${asOf}. Licensed under CC BY 4.0.`; + +result = (data?.data ?? []).map((r) => ({ ...r, total_tokens: Number(r.total_tokens), asOf, citation })); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/benchmarks.js b/plugins/OpenRouter/v1/dataStreams/scripts/benchmarks.js new file mode 100644 index 00000000..742fc9e5 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/benchmarks.js @@ -0,0 +1,63 @@ +// Flatten each source's differently shaped rows into one row per model x benchmark +const aaIndices = [ + ['intelligence_index', 'Intelligence Index'], + ['coding_index', 'Coding Index'], + ['agentic_index', 'Agentic Index'], +]; + +// Attribution OpenRouter requires per source when republishing scores +const citations = { + 'artificial-analysis': 'Source: Artificial Analysis (artificialanalysis.ai) via OpenRouter (openrouter.ai/rankings). Licensed under CC BY 4.0.', + 'design-arena': 'Source: Design Arena (www.designarena.ai) via OpenRouter (openrouter.ai/rankings). Licensed under CC BY 4.0.', + openrouter: 'Source: OpenRouter evals (openrouter.ai) via OpenRouter (openrouter.ai/rankings). Licensed under CC BY 4.0.', +}; +const asOf = data?.meta?.as_of; + +const rows = []; + +for (const r of data?.data ?? []) { + const base = { + source: r.source, + model: r.model_permaslug, + modelName: r.display_name, + asOf, + citation: citations[r.source], + }; + + if (r.source === 'artificial-analysis') { + for (const [key, benchmark] of aaIndices) { + if (r[key] == null) continue; + + rows.push({ ...base, benchmark, metric: 'index', score: r[key] }); + } + } else if (r.source === 'design-arena') { + if (r.elo == null) continue; + + rows.push({ + ...base, + benchmark: r.category, + metric: 'elo', + score: r.elo, + winRate: r.win_rate, + tasks: r.tournament_stats?.total, + avgDurationMs: r.avg_generation_time_ms, + }); + } else if (r.source === 'openrouter') { + // Search benchmarks report primary_score instead of accuracy + const score = r.accuracy ?? r.primary_score; + if (score == null) continue; + + rows.push({ + ...base, + benchmark: r.benchmark_type, + metric: r.accuracy != null ? 'accuracy' : r.primary_metric, + score, + tasks: r.total_tasks, + avgCostPerTask: r.avg_cost_per_task, + avgDurationMs: r.avg_latency_per_task_ms, + lastRun: r.last_run_timestamp, + }); + } +} + +result = rows; diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/models.js b/plugins/OpenRouter/v1/dataStreams/scripts/models.js new file mode 100644 index 00000000..5c134256 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/models.js @@ -0,0 +1,37 @@ +// Optional `models` object-picker parameter: selected objects arrive at +// context.config.models as an array, each rawId a single-element array. +// Empty/absent (including the import run) returns every model. +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +const selected = context.config?.models ?? []; +const ids = new Set(selected.map((o) => unwrap(o.rawId)).filter(Boolean)); + +// Affordability scores price per 1M tokens on a log scale so "higher is better" +// alongside the benchmark indices: 100 at FLOOR or less, 0 at the ceiling or more. +// The ceiling is the optional `affordabilityCeiling` parameter; an unset value or +// one under the field's minimum uses the default. Keep MIN_CEILING and +// DEFAULT_CEILING in sync with that field's validation.min and defaultValue. +const FLOOR = 0.01; +const MIN_CEILING = 1; +const DEFAULT_CEILING = 1000; +const requested = Number(context.config?.affordabilityCeiling); +const ceiling = Number.isFinite(requested) && requested >= MIN_CEILING ? requested : DEFAULT_CEILING; +const span = Math.log10(ceiling / FLOOR); + +// Per-token price string to a 0-100 score; null when missing, non-numeric or +// negative (variable pricing). Free models score Infinity, clamped to 100. +const affordability = (perToken) => { + const price = perToken == null || String(perToken).trim() === '' ? NaN : Number(perToken) * 1e6; + if (!Number.isFinite(price) || price < 0) { + return null; + } + + return Math.min(100, Math.max(0, (100 * Math.log10(ceiling / price)) / span)); +}; + +const models = data?.data ?? []; +result = (ids.size ? models.filter((m) => ids.has(m.id)) : models).map((m) => ({ + ...m, + inputAffordability: affordability(m.pricing?.prompt), + outputAffordability: affordability(m.pricing?.completion), + cacheReadAffordability: affordability(m.pricing?.input_cache_read) +})); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/providers.js b/plugins/OpenRouter/v1/dataStreams/scripts/providers.js new file mode 100644 index 00000000..72a8826c --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/providers.js @@ -0,0 +1,19 @@ +// Expands ISO country codes to names (US -> United States) and flattens the +// datacenters array into a comma-separated string, so both read well in tiles +// and can be indexed as Provider properties. +const countries = new Intl.DisplayNames(['en'], { type: 'region' }); + +// Falls back to the raw code if it isn't a valid region code +const country = (code) => { + try { + return code ? countries.of(code) : code; + } catch { + return code; + } +}; + +result = (data?.data ?? []).map((p) => ({ + ...p, + headquarters: country(p.headquarters), + datacenters: (p.datacenters ?? []).map(country).join(', '), +})); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/rankings.js b/plugins/OpenRouter/v1/dataStreams/scripts/rankings.js new file mode 100644 index 00000000..09160bfe --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/rankings.js @@ -0,0 +1,43 @@ +// Optional `top`: for each date (day, week, or month), keep that period's N +// biggest models and merge the rest (including OpenRouter's own `other` row) +// into one "Other" row, matching how openrouter.ai/rankings charts its top +// models. Without it, rows pass through. Every row then gets the as-of date +// and citation OpenRouter requires. + +// total_tokens arrives as a decimal string +const rows = (data?.data ?? []).map((r) => ({ ...r, total_tokens: Number(r.total_tokens) })); +const top = Number(context.config.top); + +if (!(top > 0)) { + result = rows; +} else { + const byDate = {}; + + for (const r of rows) { + const period = byDate[r.date] ?? (byDate[r.date] = []); + period.push(r); + } + + result = []; + + for (const [date, periodRows] of Object.entries(byDate).sort(([a], [b]) => a.localeCompare(b))) { + const ranked = periodRows + .filter((r) => r.model_permaslug !== 'other') + .sort((a, b) => b.total_tokens - a.total_tokens); + + const kept = ranked.slice(0, top); + const keptModels = new Set(kept.map((r) => r.model_permaslug)); + const other = periodRows + .filter((r) => !keptModels.has(r.model_permaslug)) + .reduce((sum, r) => sum + r.total_tokens, 0); + + result.push(...kept); + + if (other > 0) result.push({ date, model_permaslug: 'Other', total_tokens: other }); + } +} + +// Attribution OpenRouter requires when republishing this dataset +const asOf = data?.meta?.as_of; +const citation = `Source: OpenRouter (openrouter.ai/rankings), as of ${asOf}. Licensed under CC BY 4.0.`; +result = result.map((r) => ({ ...r, asOf, citation })); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/sessionCost.js b/plugins/OpenRouter/v1/dataStreams/scripts/sessionCost.js new file mode 100644 index 00000000..7e4e8832 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/sessionCost.js @@ -0,0 +1,25 @@ +// Labels session lengths (with a sort order, as "10-49 turns" sorts before +// "2-9 turns" alphabetically), applies the optional `models` object picker, +// and adds the as-of date and citation OpenRouter requires to every row. +const lengths = { + '1-turn': ['1 turn', 1], + '2-9-turns': ['2–9 turns', 2], + '10-49-turns': ['10–49 turns', 3], + '50-plus-turns': ['50+ turns', 4], +}; + +// Selected Model objects arrive with each property as a single-element array. +// Match on permaslug, as a :free model's session costs differ from its base's. +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +const slugs = new Set((context.config?.models ?? []).map((o) => unwrap(o.permaslug)).filter(Boolean)); + +const asOf = data?.meta?.as_of; +const citation = `Source: OpenRouter (openrouter.ai/rankings), as of ${asOf}. Licensed under CC BY 4.0.`; + +result = (data?.data ?? []) + .filter((r) => !slugs.size || slugs.has(r.model_permaslug)) + .map((r) => { + const [sessionLength, sessionLengthOrder] = lengths[r.turn_range] ?? [r.turn_range, null]; + + return { ...r, sessionLength, sessionLengthOrder, asOf, citation }; + }); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/taskClassifications.js b/plugins/OpenRouter/v1/dataStreams/scripts/taskClassifications.js new file mode 100644 index 00000000..229a98d9 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/taskClassifications.js @@ -0,0 +1,22 @@ +// One row per task classification, with its macro-category label and the +// task's most used model, plus the as-of date and citation OpenRouter requires. +// Shares are fractions (0-1) of sampled traffic. +const body = data?.data ?? {}; +const categoryLabels = Object.fromEntries((body.macro_categories ?? []).map((c) => [c.key, c.label])); + +result = (body.classifications ?? []).map((c) => { + // models isn't ordered by request share, so pick the largest explicitly + const topModel = (c.models ?? []).reduce((top, m) => (!top || m.tag_usage_share > top.tag_usage_share ? m : top), null); + + return { + tag: c.tag, + task: c.display_name, + category: categoryLabels[c.macro_category] ?? c.macro_category, + usageShare: c.usage_share, + tokenShare: c.token_share, + topModel: topModel?.id ?? null, + topModelUsageShare: topModel?.tag_usage_share ?? null, + asOf: body.as_of, + citation: `Source: OpenRouter (openrouter.ai/rankings), as of ${body.as_of}. Licensed under CC BY 4.0.`, + }; +}); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/usage.js b/plugins/OpenRouter/v1/dataStreams/scripts/usage.js new file mode 100644 index 00000000..642bdcea --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/usage.js @@ -0,0 +1,35 @@ +// Normalises analytics rows for the usage and performance streams: one column +// per requested metric, named as OpenRouter names it. The time key is suffixed +// with the granularity (date__day, or created_at__day for raw-view fields like +// latency and provider) and large counts arrive as strings. +// cost_per_million_tokens isn't an OpenRouter metric; it's derived per row when +// total_usage and tokens_total are both requested. +const body = data?.data ?? {}; +const groupBy = context.config.groupBy; + +if (body.metadata?.truncated) { + api.report.warning( + 'Results were truncated by OpenRouter; narrow the timeframe or filter to specific objects', + ); +} + +const isDateKey = (key) => /__(minute|hour|day|week|month)$/.test(key); + +result = (body.data ?? []) + .map((row) => { + const out = { date: null, group: groupBy ? row[groupBy] ?? null : null }; + + // Numeric strings become numbers; anything else passes through untouched + for (const [key, value] of Object.entries(row)) { + if (isDateKey(key)) out.date = value; + else if (key !== groupBy) out[key] = value != null && Number.isFinite(Number(value)) ? Number(value) : value; + } + + if ('total_usage' in out && 'tokens_total' in out) { + out.cost_per_million_tokens = + out.tokens_total && out.total_usage != null ? (out.total_usage / out.tokens_total) * 1e6 : null; + } + + return out; + }) + .filter((row) => row.date); diff --git a/plugins/OpenRouter/v1/dataStreams/scripts/workspaces.js b/plugins/OpenRouter/v1/dataStreams/scripts/workspaces.js new file mode 100644 index 00000000..b6b83ce5 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/scripts/workspaces.js @@ -0,0 +1,11 @@ +// Optional `workspaces` object-picker parameter: selected objects arrive at +// context.config.workspaces, each rawId a single-element array. Empty/absent +// (including the import run) returns every workspace. Also flattens the +// disabled server tools list into a comma-separated string for tables. +const unwrap = (v) => (Array.isArray(v) ? v[0] : v); +const selected = context.config?.workspaces ?? []; +const ids = new Set(selected.map((o) => unwrap(o.rawId)).filter(Boolean)); + +result = (data?.data ?? []) + .filter((w) => !ids.size || ids.has(w.id)) + .map((w) => ({ ...w, disabled_server_tools: w.disabled_server_tools?.join(', ') || null })); diff --git a/plugins/OpenRouter/v1/dataStreams/sessionCost.json b/plugins/OpenRouter/v1/dataStreams/sessionCost.json new file mode 100644 index 00000000..2a4a060d --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/sessionCost.json @@ -0,0 +1,184 @@ +{ + "name": "sessionCost", + "displayName": "Session Cost", + "description": "Median cost of one coding-agent session by harness, model, and session length (from OpenRouter's public rankings, refreshed weekly)", + "tags": [ + "Models", + "Cost" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "datasets/session-cost", + "paging": { + "mode": "offset", + "pageSize": { + "realm": "queryArg", + "path": "limit", + "value": "500" + }, + "offset": { + "mode": "row", + "rowCountIn": { + "realm": "payloadArraySize", + "path": "data" + }, + "base": 0 + }, + "out": { + "realm": "queryArg", + "path": "offset" + } + }, + "getArgs": [ + { + "key": "app_slug", + "value": "{{harness || null}}" + }, + { + "key": "turn_range", + "value": "{{turnRange || null}}" + } + ], + "headers": [], + "postRequestScript": "sessionCost.js" + }, + "matches": "none", + "metadata": [ + { + "name": "app_name", + "displayName": "Harness", + "shape": "string", + "role": "label" + }, + { + "name": "app_slug", + "displayName": "Harness ID", + "shape": "string", + "visible": false + }, + { + "name": "model_permaslug", + "displayName": "Model", + "shape": "string" + }, + { + "name": "turn_range", + "displayName": "Session Length ID", + "shape": "string", + "visible": false + }, + { + "name": "sessionLength", + "displayName": "Session Length", + "shape": "string" + }, + { + "name": "sessionLengthOrder", + "displayName": "Session Length Order", + "shape": "number", + "visible": false + }, + { + "name": "median_session_cost_usd", + "displayName": "Median Session Cost", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 4 + } + ], + "role": "value" + }, + { + "name": "asOf", + "displayName": "As Of", + "shape": "date", + "visible": false + }, + { + "name": "citation", + "displayName": "Citation", + "shape": "string", + "visible": false + } + ], + "options": { + "minimumRequestIntervalSeconds": 86400 + }, + "timeframes": false, + "ui": [ + { + "type": "autocomplete", + "name": "harness", + "label": "Harness", + "isMulti": false, + "isClearable": true, + "allowCustomValues": true, + "help": "Select a coding-agent harness, or enter the slug of another harness OpenRouter publishes", + "data": { + "source": "fixed", + "values": [ + { + "value": "claude-code", + "label": "Claude Code" + }, + { + "value": "codex", + "label": "Codex" + }, + { + "value": "hermes-agent", + "label": "Hermes Agent" + }, + { + "value": "kilo-code", + "label": "Kilo Code" + } + ] + } + }, + { + "type": "autocomplete", + "name": "turnRange", + "label": "Session length", + "isMulti": false, + "isClearable": true, + "data": { + "source": "fixed", + "values": [ + { + "value": "1-turn", + "label": "1 turn" + }, + { + "value": "2-9-turns", + "label": "2\u20139 turns" + }, + { + "value": "10-49-turns", + "label": "10\u201349 turns" + }, + { + "value": "50-plus-turns", + "label": "50+ turns" + } + ] + } + }, + { + "type": "objects", + "name": "models", + "label": "Model(s)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model" + ] + } + } + } + ] +} diff --git a/plugins/OpenRouter/v1/dataStreams/taskClassifications.json b/plugins/OpenRouter/v1/dataStreams/taskClassifications.json new file mode 100644 index 00000000..e992d717 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/taskClassifications.json @@ -0,0 +1,92 @@ +{ + "name": "taskClassifications", + "displayName": "Task Classifications", + "description": "Share of OpenRouter traffic by task type over the last 7 days, with each task's most used model (from OpenRouter's public rankings)", + "tags": [ + "Models", + "Usage" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "classifications/task", + "paging": { + "mode": "none" + }, + "getArgs": [], + "headers": [], + "postRequestScript": "taskClassifications.js" + }, + "matches": "none", + "metadata": [ + { + "name": "tag", + "displayName": "Tag", + "shape": "string", + "visible": false + }, + { + "name": "task", + "displayName": "Task", + "shape": "string", + "role": "label" + }, + { + "name": "category", + "displayName": "Category", + "shape": "string" + }, + { + "name": "usageShare", + "displayName": "Request Share", + "shape": [ + "percent", + { + "asZeroToOne": true + } + ], + "role": "value" + }, + { + "name": "tokenShare", + "displayName": "Token Share", + "shape": [ + "percent", + { + "asZeroToOne": true + } + ] + }, + { + "name": "topModel", + "displayName": "Top Model", + "shape": "string" + }, + { + "name": "topModelUsageShare", + "displayName": "Top Model Share Of Task Requests", + "shape": [ + "percent", + { + "asZeroToOne": true + } + ] + }, + { + "name": "asOf", + "displayName": "As Of", + "shape": "date", + "visible": false + }, + { + "name": "citation", + "displayName": "Citation", + "shape": "string", + "visible": false + } + ], + "options": { + "minimumRequestIntervalSeconds": 86400 + }, + "timeframes": false +} diff --git a/plugins/OpenRouter/v1/dataStreams/usage.json b/plugins/OpenRouter/v1/dataStreams/usage.json new file mode 100644 index 00000000..2e6e1cf1 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/usage.json @@ -0,0 +1,225 @@ +{ + "name": "usage", + "displayName": "Usage", + "description": "Spend, requests, and tokens over time, optionally grouped by model, provider, workspace, API key, or app (requires a management key)", + "tags": [ + "Usage", + "Cost" + ], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "post", + "endpointPath": "analytics/query", + "paging": { + "mode": "none" + }, + "getArgs": [], + "headers": [], + "postBody": "{{ (() => { const iso = (d) => new Date(d).toISOString().slice(0, 19) + 'Z'; const days = (new Date(timeframe.end) - new Date(timeframe.start)) / 864e5; const granularity = days <= 2 ? 'hour' : days <= 31 ? 'day' : days <= 92 ? 'week' : 'month'; const selected = typeof filterObjects !== 'undefined' && Array.isArray(filterObjects) ? filterObjects : []; const one = (v) => (Array.isArray(v) ? v[0] : v); const idsOf = (type, ...props) => [...new Set(selected.filter((o) => one(o.sourceType) === type).flatMap((o) => props.map((p) => one(o[p]))).filter(Boolean))]; const rules = [ ['model', idsOf('Model', 'rawId', 'canonical_slug')], ['provider', idsOf('Provider', 'name')], ['workspace', idsOf('Workspace', 'rawId')], ['api_key_id', idsOf('API Key', 'rawId')] ]; const filters = rules.filter(([, values]) => values.length).map(([field, value]) => ({ field, operator: 'in', value })); return JSON.stringify({ metrics: ['total_usage', 'byok_usage', 'request_count', 'tokens_total', 'tokens_prompt', 'tokens_completion', 'reasoning_tokens', 'cached_tokens'], dimensions: typeof groupBy !== 'undefined' && groupBy ? [groupBy] : [], filters, granularity, time_range: { start: iso(timeframe.start), end: iso(timeframe.end) } }); })() }}", + "postRequestScript": "usage.js" + }, + "matches": "none", + "ui": [ + { + "type": "autocomplete", + "name": "groupBy", + "label": "Group by", + "help": "Select a dimension, or enter any dimension from [OpenRouter's analytics dimensions](https://openrouter.ai/docs/api/api-reference/analytics/get-available-analytics-metrics-and-dimensions). Request details are limited to 31 days.", + "allowCustomValues": true, + "isMulti": false, + "isClearable": true, + "data": { + "source": "fixed", + "values": [ + { + "label": "Any timeframe", + "options": [ + { + "value": "model", + "label": "Model" + }, + { + "value": "workspace", + "label": "Workspace" + }, + { + "value": "api_key_id", + "label": "API key" + }, + { + "value": "app", + "label": "App" + }, + { + "value": "user", + "label": "User" + } + ] + }, + { + "label": "Request details (31 days max)", + "options": [ + { + "value": "provider", + "label": "Provider" + }, + { + "value": "origin", + "label": "Origin" + }, + { + "value": "country", + "label": "Country" + }, + { + "value": "finish_reason", + "label": "Finish reason" + }, + { + "value": "streamed", + "label": "Streamed" + } + ] + } + ] + } + }, + { + "type": "objects", + "name": "filterObjects", + "label": "Filter to objects (optional)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model", + "Provider", + "Workspace", + "API Key" + ] + } + } + } + ], + "metadata": [ + { + "name": "date", + "displayName": "Date", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ], + "role": "timestamp" + }, + { + "name": "group", + "displayName": "Group", + "shape": "string", + "role": "label" + }, + { + "name": "total_usage", + "displayName": "Spend", + "shape": "usd", + "role": "value" + }, + { + "name": "byok_usage", + "displayName": "BYOK Spend", + "shape": "usd" + }, + { + "name": "request_count", + "displayName": "Requests", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "tokens_total", + "displayName": "Total Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "tokens_prompt", + "displayName": "Prompt Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "tokens_completion", + "displayName": "Completion Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "reasoning_tokens", + "displayName": "Reasoning Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "cached_tokens", + "displayName": "Cached Tokens", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "cost_per_million_tokens", + "displayName": "Cost Per 1M Tokens", + "shape": [ + "usd", + { + "decimalPlaces": 4 + } + ] + } + ], + "timeframes": [ + "last12hours", + "last24hours", + "last7days", + "last30days", + "thisMonth", + "lastMonth", + "thisQuarter", + "lastQuarter", + "thisYear" + ], + "defaultShaping": { + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + } + } +} diff --git a/plugins/OpenRouter/v1/dataStreams/workspaces.json b/plugins/OpenRouter/v1/dataStreams/workspaces.json new file mode 100644 index 00000000..ebb79875 --- /dev/null +++ b/plugins/OpenRouter/v1/dataStreams/workspaces.json @@ -0,0 +1,124 @@ +{ + "name": "workspaces", + "displayName": "Workspaces", + "description": "Workspaces in the OpenRouter account, with default models, logging, and budget settings (requires a management key)", + "tags": ["Workspaces"], + "baseDataSourceName": "httpRequestUnscoped", + "config": { + "httpMethod": "get", + "endpointPath": "workspaces", + "paging": { + "mode": "offset", + "pageSize": { "realm": "queryArg", "path": "limit", "value": "100" }, + "offset": { + "mode": "row", + "rowCountIn": { "realm": "payloadArraySize", "path": "data" }, + "base": 0 + }, + "out": { "realm": "queryArg", "path": "offset" } + }, + "getArgs": [], + "headers": [], + "postRequestScript": "workspaces.js" + }, + "matches": "none", + "metadata": [ + { + "name": "id", + "displayName": "Workspace ID", + "shape": "string" + }, + { + "name": "name", + "displayName": "Name", + "shape": "string", + "role": "label" + }, + { + "name": "slug", + "displayName": "Slug", + "shape": "string" + }, + { + "name": "description", + "displayName": "Description", + "shape": "string" + }, + { + "name": "default_text_model", + "displayName": "Default Text Model", + "shape": "string" + }, + { + "name": "default_image_model", + "displayName": "Default Image Model", + "shape": "string" + }, + { + "name": "default_provider_sort", + "displayName": "Default Provider Sort", + "shape": "string" + }, + { + "name": "disabled_server_tools", + "displayName": "Disabled Server Tools", + "shape": "string" + }, + { + "name": "include_byok_in_budgets", + "displayName": "BYOK In Budgets", + "shape": "boolean" + }, + { + "name": "is_observability_io_logging_enabled", + "displayName": "Private Logging", + "shape": "boolean" + }, + { + "name": "io_logging_sampling_rate", + "displayName": "Private Logging Sample Rate", + "shape": [ + "percent", + { + "asZeroToOne": true + } + ] + }, + { + "name": "is_observability_broadcast_enabled", + "displayName": "Broadcast", + "shape": "boolean" + }, + { + "name": "is_data_discount_logging_enabled", + "displayName": "Data Discount Logging", + "shape": "boolean" + }, + { + "name": "created_at", + "displayName": "Created", + "shape": "date" + }, + { + "name": "updated_at", + "displayName": "Updated", + "shape": "date" + } + ], + "timeframes": false, + "ui": [ + { + "type": "objects", + "name": "workspaces", + "label": "Workspace(s)", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Workspace" + ] + } + } + } + ] +} diff --git a/plugins/OpenRouter/v1/defaultContent/apiKey.dash.json b/plugins/OpenRouter/v1/defaultContent/apiKey.dash.json new file mode 100644 index 00000000..fc495938 --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/apiKey.dash.json @@ -0,0 +1,601 @@ +{ + "name": "API Key", + "schemaVersion": "1.5", + "timeframe": "last30days", + "variables": [ + "{{variables.[API Key]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "d64c1f90-53a1-442e-9f73-f3d17435b749", + "x": 0, + "y": 0, + "w": 1, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "", + "timeframe": "none", + "dataStream": { + "id": "datastream-properties", + "name": "properties", + "metadata": [ + { + "name": "expiryStatus", + "displayName": "Expiry Status", + "computed": true, + "valueExpression": "{{{{raw}}}}{{ (v => { if (!v) return 'success'; const days = (new Date(v) - Date.now()) / 864e5; return days < 1 ? 'error' : days < 5 ? 'warning' : 'success'; })([].concat($['expires_at'])[0]) }}{{{{/raw}}}}", + "shape": [ + "state", + { + "map": { + "error": [ + "error" + ], + "warning": [ + "warning" + ], + "success": [ + "success" + ] + } + } + ] + } + ] + }, + "scope": { + "scope": "{{scopes.[API Keys]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[API Key]}}" + }, + "variables": [ + "{{variables.[API Key]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "workspace_id", + "title": "Workspace ID", + "renderer": { + "type": "text" + } + }, + { + "field": "disabled", + "title": "Disabled", + "renderer": { + "type": "boolean", + "trueColor": "var(--statusErrorPrimary)", + "falseColor": "var(--textSecondary)" + } + }, + { + "field": "created_at", + "title": "Created", + "renderer": { + "type": "date" + } + }, + { + "field": "expires_at", + "title": "Expires", + "renderer": { + "type": "date" + } + }, + { + "field": "expiryStatus", + "title": "Expiry Status", + "renderer": { + "type": "status" + } + } + ] + }, + "style": { + "richTableTranspose": true + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true, + "columnOrder": [ + "name", + "workspace_id", + "disabled", + "created_at", + "expires_at", + "expiryStatus" + ], + "hiddenColumns": [ + "id", + "links", + "type", + "label", + "sourceId", + "sourceType", + "sourceName", + "rawId" + ] + } + } + } + } + }, + { + "i": "a69c68dd-2968-4ac8-acc6-a224d85d7c37", + "x": 1, + "y": 0, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[API Keys]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[API Key]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[API Key]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "19cc22f9-e6fd-4c23-bd89-7e925a85849a", + "x": 1, + "y": 2, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Requests Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[API Keys]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[API Key]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "request_count", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[API Key]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "request_count", + "type": "quantitative", + "title": "Requests" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Requests", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "request_count" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Requests", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "5c1cfeba-46df-41a0-aebc-9fcfb2a35a81", + "x": 1, + "y": 4, + "w": 3, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Model", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model", + "filterObjects": { + "scope": "{{scopes.[API Keys]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[API Key]}}" + } + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[API Key]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "Model" + }, + "y": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "group_uniqueValues", + "yAxisData": [ + "total_usage_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "Model", + "yAxisLabel": "Spend ($)", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "7e935a7c-91fa-4ead-a346-f440f059bff3", + "x": 0, + "y": 4, + "w": 1, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend Limit", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "-- apiKeys is listed per workspace, so pick this page's key out by its hash;\n-- keys without a limit return no row\nSELECT\n k.name,\n k.limitUsed\nFROM Keys k\nJOIN ThisKey p ON p.rawId = k.hash\nWHERE k.limitUsed IS NOT NULL", + "tables": [ + { + "tableName": "Keys", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[apiKeys]}}", + "name": "apiKeys", + "pluginConfigId": "{{configId}}" + }, + "scope": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "ThisKey", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[API Keys]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[API Key]}}" + }, + "variables": [ + "{{variables.[API Key]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "name", + "displayName": "API Key", + "shape": "string", + "role": "label" + }, + { + "name": "limitUsed", + "displayName": "Limit Used (%)", + "shape": [ + "number", + { + "decimalPlaces": 1 + } + ], + "role": "value" + } + ] + }, + "variables": [ + "{{variables.[API Key]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "gauge", + "encoding": { + "value": { + "field": "limitUsed", + "type": "quantitative", + "title": "Limit Used (%)" + } + }, + "style": { + "gaugeMin": 0, + "gaugeMax": 100, + "gaugeLabelText": "Limit Used", + "labelFormat": "{{{{raw}}}}{{value}}%{{{{/raw}}}}", + "gaugeBands": [ + { + "to": 0.8, + "color": "#91cc75" + }, + { + "to": 0.95, + "color": "#fac858" + }, + { + "to": 1, + "color": "#ee6666" + } + ] + } + } + }, + "visualisation": { + "type": "data-stream-gauge", + "config": { + "data-stream-gauge": { + "value": { + "type": "mean", + "columns": [ + "limitUsed" + ] + }, + "label": "Limit Used (%)", + "minimum": 0, + "maximum": 100 + } + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/ecosystem.dash.json b/plugins/OpenRouter/v1/defaultContent/ecosystem.dash.json new file mode 100644 index 00000000..0ef1a0ad --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/ecosystem.dash.json @@ -0,0 +1,452 @@ +{ + "name": "Ecosystem", + "schemaVersion": "1.5", + "timeframe": "last30days", + "dashboard": { + "_type": "layout/grid", + "columns": 6, + "version": 1, + "contents": [ + { + "i": "adfbf427-f14a-479a-ba73-0992167fb17c", + "x": 0, + "y": 0, + "w": 6, + "h": 5, + "config": { + "_type": "tile/data-stream", + "title": "Trending Apps On OpenRouter", + "description": "Up to 25 public apps whose tokens grew the most on OpenRouter compared with the three previous periods of the same length, sized by tokens.", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[appRankings]}}", + "name": "appRankings", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "rankBy": "trending" + }, + "sort": { + "by": [ + [ + "rank", + "asc" + ] + ], + "top": 25 + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "treemap", + "encoding": { + "label": { + "field": "app_name", + "type": "nominal", + "title": "App" + }, + "value": { + "field": "total_tokens", + "type": "quantitative", + "title": "Tokens" + } + }, + "style": { + "legendPosition": "none" + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "app_name", + "yAxisData": [ + "total_tokens" + ], + "xAxisGroup": "none", + "xAxisLabel": "App", + "yAxisLabel": "Tokens", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "c0e54f6c-51f5-4708-be03-4b9b4fdb1c2a", + "x": 0, + "y": 5, + "w": 3, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Top Apps On OpenRouter", + "description": "Public apps with the most tokens on OpenRouter.", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[appRankings]}}", + "name": "appRankings", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "rankBy": "popular" + }, + "sort": { + "by": [ + [ + "rank", + "asc" + ] + ], + "top": 10 + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "app_name", + "type": "nominal", + "title": "App" + }, + "y": { + "field": "total_tokens", + "type": "quantitative", + "title": "Tokens" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "app_name", + "yAxisData": [ + "total_tokens" + ], + "xAxisGroup": "none", + "xAxisLabel": "App", + "yAxisLabel": "Tokens", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "51dfb910-bec4-45ea-b9a2-683c1574f00f", + "x": 0, + "y": 9, + "w": 4, + "h": 5, + "config": { + "_type": "tile/data-stream", + "title": "Tasks On OpenRouter", + "description": "Task types ranked by their share of requests on OpenRouter.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[taskClassifications]}}", + "name": "taskClassifications", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "usageShare", + "desc" + ] + ] + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "treemap", + "encoding": { + "parent": { + "field": "category", + "type": "nominal", + "title": "Category" + }, + "label": { + "field": "task", + "type": "nominal", + "title": "Task" + }, + "value": { + "field": "usageShare", + "type": "quantitative", + "title": "Request Share" + } + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "task", + "yAxisData": [ + "usageShare" + ], + "xAxisGroup": "none", + "xAxisLabel": "Task", + "yAxisLabel": "Request Share", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "0472205a-cff6-442b-93ec-2b063b6aa157", + "x": 4, + "y": 9, + "w": 2, + "h": 5, + "config": { + "_type": "tile/data-stream", + "title": "Request Share By Task Category", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[taskClassifications]}}", + "name": "taskClassifications", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "category", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "usageShare" + ] + } + ] + }, + "sort": { + "by": [ + [ + "usageShare_sum", + "desc" + ] + ] + }, + "metadata": [ + { + "name": "usageShare_sum", + "shape": [ + "percent", + { + "asZeroToOne": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "category_uniqueValues", + "type": "nominal", + "title": "Category" + }, + "value": { + "field": "usageShare_sum", + "type": "quantitative", + "title": "Request Share" + } + }, + "style": { + "pieInnerRadius": 55, + "legendPosition": "bottom" + } + } + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "usageShare_sum", + "labelColumn": "category_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + } + } + }, + { + "i": "488c8839-874c-4a1e-a32f-5318792e4b68", + "x": 3, + "y": 5, + "w": 3, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Providers By Headquarters", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[providers]}}", + "name": "providers", + "pluginConfigId": "{{configId}}", + "group": { + "by": [ + [ + "headquarters", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "count" + } + ] + }, + "sort": { + "by": [ + [ + "count", + "desc" + ] + ] + }, + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "headquarters", + "operation": "notempty" + } + ] + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "headquarters_uniqueValues", + "type": "nominal", + "title": "Headquarters" + }, + "value": { + "field": "count", + "type": "quantitative", + "title": "Providers" + } + }, + "style": { + "legendPosition": "bottom" + } + } + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "count", + "labelColumn": "headquarters_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + } + } + }, + { + "i": "84870314-2f06-4a46-af2b-ca3f40bfa2f2", + "x": 0, + "y": 14, + "w": 6, + "h": 1, + "config": { + "_type": "tile/text", + "title": "", + "description": "", + "visualisation": { + "config": { + "content": "Apps: OpenRouter ([openrouter.ai/apps](https://openrouter.ai/apps)). Tasks: OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)), covering the 7 days to yesterday (UTC). \nLicensed under CC BY 4.0.", + "fontSize": 12, + "align": "left", + "autoSize": true + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/manifest.json b/plugins/OpenRouter/v1/defaultContent/manifest.json new file mode 100644 index 00000000..d572c741 --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/manifest.json @@ -0,0 +1,36 @@ +{ + "items": [ + { + "name": "overview", + "type": "dashboard" + }, + { + "name": "modelLeaderboards", + "type": "dashboard" + }, + { + "name": "modelComparison", + "type": "dashboard" + }, + { + "name": "ecosystem", + "type": "dashboard" + }, + { + "name": "model", + "type": "dashboard" + }, + { + "name": "provider", + "type": "dashboard" + }, + { + "name": "workspace", + "type": "dashboard" + }, + { + "name": "apiKey", + "type": "dashboard" + } + ] +} diff --git a/plugins/OpenRouter/v1/defaultContent/model.dash.json b/plugins/OpenRouter/v1/defaultContent/model.dash.json new file mode 100644 index 00000000..12516b31 --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/model.dash.json @@ -0,0 +1,1704 @@ +{ + "name": "Model", + "schemaVersion": "1.5", + "timeframe": "last30days", + "variables": [ + "{{variables.[Model]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "f84087cc-45c8-4d32-9422-8e1b76bd7d37", + "x": 0, + "y": 0, + "w": 1, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "", + "timeframe": "none", + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "author", + "title": "Author", + "renderer": { + "type": "text" + } + }, + { + "field": "canonical_slug", + "title": "Slug", + "renderer": { + "type": "text" + } + }, + { + "field": "context_length", + "title": "Context", + "renderer": { + "type": "number", + "compact": true + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableFontSize": 12 + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true, + "columnOrder": [ + "name", + "author", + "canonical_slug", + "context_length" + ], + "hiddenColumns": [ + "id", + "links", + "type", + "label", + "sourceId", + "sourceType", + "sourceName", + "rawId", + "permaslug" + ] + } + } + } + } + }, + { + "i": "aadaac03-632a-4219-8d5c-3ddb8696d938", + "x": 1, + "y": 0, + "w": 1, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Pricing And Capabilities", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "models": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + } + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "inputPrice", + "title": "Input $/1M", + "renderer": { + "type": "text" + } + }, + { + "field": "outputPrice", + "title": "Output $/1M", + "renderer": { + "type": "text" + } + }, + { + "field": "cacheReadPrice", + "title": "Cache Read $/1M", + "renderer": { + "type": "text" + } + }, + { + "field": "context_length", + "title": "Context", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "top_provider.max_completion_tokens", + "title": "Max Output", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "inputModalities", + "title": "Input", + "renderer": { + "type": "tag-list" + } + }, + { + "field": "outputModalities", + "title": "Output", + "renderer": { + "type": "tag-list" + } + }, + { + "field": "benchmarks.artificial_analysis.intelligence_index", + "title": "Intelligence", + "renderer": { + "type": "number", + "decimals": 1 + } + }, + { + "field": "benchmarks.artificial_analysis.coding_index", + "title": "Coding", + "renderer": { + "type": "number", + "decimals": 1 + } + }, + { + "field": "benchmarks.artificial_analysis.agentic_index", + "title": "Agentic", + "renderer": { + "type": "number", + "decimals": 1 + } + }, + { + "field": "knowledge_cutoff", + "title": "Knowledge Cutoff", + "renderer": { + "type": "date" + } + }, + { + "field": "expiration_date", + "title": "Expires", + "renderer": { + "type": "date" + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableFontSize": 12, + "richTableNoHeader": true + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true, + "columnOrder": [ + "inputPrice", + "outputPrice", + "cacheReadPrice", + "context_length", + "top_provider.max_completion_tokens", + "inputModalities", + "outputModalities", + "benchmarks.artificial_analysis.intelligence_index", + "benchmarks.artificial_analysis.coding_index", + "benchmarks.artificial_analysis.agentic_index", + "knowledge_cutoff", + "created", + "expiration_date" + ], + "hiddenColumns": [ + "id", + "name", + "author", + "canonical_slug", + "permaslug", + "pricing.prompt", + "pricing.completion", + "pricing.input_cache_read", + "inputAffordability", + "outputAffordability", + "cacheReadAffordability", + "architecture.input_modalities", + "architecture.output_modalities" + ] + } + } + } + } + }, + { + "i": "5ddeb1c0-9941-4264-8695-b0d2e3a235ab", + "x": 2, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Spend", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "be276411-9f7c-4567-9d57-3222ced1f027", + "x": 2, + "y": 2, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Requests", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "request_count", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "request_count", + "type": "quantitative", + "title": "Requests" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Requests", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "request_count" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Requests", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "7a60262f-2a6e-4c04-90c8-d81015d2ba20", + "x": 0, + "y": 4, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Provider Status", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}" + }, + "scope": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "statusGrid", + "encoding": { + "label": { + "field": "tag", + "type": "nominal", + "title": "Endpoint" + }, + "status": { + "field": "health", + "type": "nominal", + "title": "Status" + }, + "value": { + "field": "uptime_last_5m", + "type": "quantitative", + "title": "Uptime (5m)" + } + }, + "style": { + "statusGridColumnsPerRow": 4 + } + } + }, + "visualisation": { + "type": "data-stream-blocks", + "config": { + "data-stream-blocks": { + "labelColumn": "tag", + "stateColumn": "health", + "sublabel": "uptime_last_5m", + "linkColumn": "none", + "columns": 4 + } + } + } + } + }, + { + "i": "2abeda4d-5ec9-4f59-8523-910763ad6575", + "x": 2, + "y": 4, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Provider Price Vs Throughput", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}" + }, + "scope": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scatter", + "encoding": { + "x": { + "field": "outputPrice", + "type": "quantitative", + "title": "Output Price ($/1M Tokens)" + }, + "y": { + "field": "throughput_last_30m.p50", + "type": "quantitative", + "title": "Throughput (Tokens/s)" + }, + "color": { + "field": "provider_name", + "type": "nominal", + "title": "Provider" + } + }, + "style": { + "legendPosition": "none", + "cartesianShowXAxisTitle": true, + "cartesianXAxisTitle": "Output Price ($/1M Tokens)", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Throughput (Tokens/s)" + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "provider_name", + "tag", + "outputPrice", + "throughput_last_30m.p50" + ], + "hiddenColumns": [ + "health", + "quantization", + "context_length", + "inputPrice", + "cacheReadPrice", + "uptime_last_5m", + "uptime_last_30m", + "uptime_last_1d", + "latency_last_30m.p50", + "latency_last_30m.p90", + "model_name", + "pricing.prompt", + "pricing.completion", + "status", + "pricing.input_cache_read", + "latency_last_30m.p75", + "latency_last_30m.p99" + ] + } + } + } + } + }, + { + "i": "47caf67c-f374-458b-afd2-7ba9b3cc4979", + "x": 0, + "y": 7, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Spend By Provider (Last 30 Days)", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "provider", + "filterObjects": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + }, + "series": { + "field": "group", + "type": "nominal", + "title": "Provider" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "group", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "152fb443-9a06-4eea-a5c4-a4dafd4c0277", + "x": 2, + "y": 7, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Cost Per 1M Tokens By Provider (Last 30 Days)", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "provider", + "filterObjects": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "cost_per_million_tokens", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 4 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "cost_per_million_tokens", + "type": "quantitative", + "title": "Cost per 1M tokens ($)" + }, + "series": { + "field": "group", + "type": "nominal", + "title": "Provider" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Cost per 1M tokens ($)" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "cost_per_million_tokens" + ], + "seriesColumn": "group", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Cost per 1M tokens ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "0e72d465-f7f3-42ad-8a6f-2b7a91a8850a", + "x": 0, + "y": 10, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Latency (Last 30 Days)", + "description": "Line: your median (p50) latency each day. Shaded band: p50 to p90, so 9 in 10 requests were faster than its top edge.", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[performance]}}", + "name": "performance", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "p50_latency", + "shape": "milliseconds" + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "p50_latency", + "type": "quantitative", + "title": "p50" + }, + "low": { + "field": "p50_latency", + "type": "quantitative", + "title": "p50" + }, + "high": { + "field": "p90_latency", + "type": "quantitative", + "title": "p90" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Latency" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "p50_latency", + "p90_latency" + ], + "seriesColumn": "none", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Latency", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "0fe94a89-e194-4ce1-bf03-3495bec434cd", + "x": 2, + "y": 10, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Time To First Token (Last 30 Days)", + "description": "Line: your median (p50) time to first token each day. Shaded band: p50 to p90, so 9 in 10 requests were faster than its top edge.", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[performance]}}", + "name": "performance", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "p50_total_time_to_first_token", + "shape": "milliseconds" + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "p50_total_time_to_first_token", + "type": "quantitative", + "title": "p50" + }, + "low": { + "field": "p50_total_time_to_first_token", + "type": "quantitative", + "title": "p50" + }, + "high": { + "field": "p90_total_time_to_first_token", + "type": "quantitative", + "title": "p90" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Time To First Token" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "p50_total_time_to_first_token", + "p90_total_time_to_first_token" + ], + "seriesColumn": "none", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Time To First Token", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "21bb9221-3105-46cb-a988-b677dafef3e9", + "x": 0, + "y": 12, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Providers", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "uptime_last_1d", + "desc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "provider_name", + "title": "Provider", + "renderer": { + "type": "text" + } + }, + { + "field": "health", + "title": "Status", + "renderer": { + "type": "status" + } + }, + { + "field": "tag", + "title": "Endpoint", + "renderer": { + "type": "text" + } + }, + { + "field": "quantization", + "title": "Quantization", + "renderer": { + "type": "text" + } + }, + { + "field": "context_length", + "title": "Context", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "inputPrice", + "title": "Input $/1M", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "outputPrice", + "title": "Output $/1M", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "cacheReadPrice", + "title": "Cache Read $/1M", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "uptime_last_30m", + "title": "Uptime (30m)", + "align": "right", + "renderer": { + "type": "number", + "decimals": 1, + "suffix": "%", + "thresholds": [ + { + "to": 95, + "color": "var(--statusErrorPrimary)" + }, + { + "to": 99, + "color": "var(--statusWarningPrimary)" + }, + { + "to": 100, + "color": "var(--statusHealthyPrimary)" + } + ] + } + }, + { + "field": "uptime_last_1d", + "title": "Uptime (1d)", + "align": "right", + "renderer": { + "type": "number", + "decimals": 1, + "suffix": "%", + "thresholds": [ + { + "to": 95, + "color": "var(--statusErrorPrimary)" + }, + { + "to": 99, + "color": "var(--statusWarningPrimary)" + }, + { + "to": 100, + "color": "var(--statusHealthyPrimary)" + } + ] + } + }, + { + "field": "latency_last_30m.p50", + "title": "Latency p50", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "throughput_last_30m.p50", + "title": "Tokens/s p50", + "align": "right", + "renderer": { + "type": "number", + "decimals": 1 + } + } + ] + }, + "style": {} + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "provider_name", + "health", + "tag", + "quantization", + "context_length", + "inputPrice", + "outputPrice", + "cacheReadPrice", + "uptime_last_5m", + "uptime_last_30m", + "uptime_last_1d", + "latency_last_30m.p50", + "latency_last_30m.p90", + "throughput_last_30m.p50" + ], + "hiddenColumns": [ + "model_name", + "pricing.prompt", + "pricing.completion", + "status", + "pricing.input_cache_read" + ] + } + } + } + } + }, + { + "i": "270958b4-1c9b-4063-8f93-f9908be878c4", + "x": 0, + "y": 15, + "w": 4, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Session Cost By Harness", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionCost]}}", + "name": "sessionCost", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "models": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + }, + "sort": { + "by": [ + [ + "sessionLengthOrder", + "asc" + ], + [ + "app_name", + "asc" + ] + ] + } + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "app_name", + "type": "nominal", + "title": "Harness" + }, + "y": { + "field": "median_session_cost_usd", + "type": "quantitative", + "title": "Median Session Cost ($)" + }, + "series": { + "field": "sessionLength", + "type": "nominal", + "title": "Session Length" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianStack": "off", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Median Session Cost ($)" + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "app_name", + "sessionLength", + "median_session_cost_usd", + "model_permaslug" + ], + "hiddenColumns": [ + "app_slug", + "turn_range", + "sessionLengthOrder", + "asOf", + "citation" + ] + } + } + } + } + }, + { + "i": "c4ac55e8-5333-45eb-ace6-c5e7aad15b6f", + "x": 0, + "y": 19, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Latency By Provider", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "SELECT\n e.tag AS endpoint,\n p.percentile,\n CASE p.percentile WHEN 'p50' THEN e.\"latency_last_30m.p50\" ELSE e.\"latency_last_30m.p90\" END AS latency\nFROM Endpoints e, (VALUES ('p50'), ('p90')) AS p(percentile)\nORDER BY e.\"latency_last_30m.p50\" NULLS LAST, e.tag, p.percentile", + "tables": [ + { + "tableName": "Endpoints", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}" + }, + "scope": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + }, + "variables": [ + "{{variables.[Model]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "endpoint", + "displayName": "Endpoint", + "shape": "string", + "role": "label" + }, + { + "name": "percentile", + "displayName": "Percentile", + "shape": "string" + }, + { + "name": "latency", + "displayName": "Latency", + "shape": "milliseconds" + } + ] + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "endpoint", + "type": "nominal", + "title": "Endpoint" + }, + "y": { + "field": "latency", + "type": "quantitative", + "title": "Latency" + }, + "series": { + "field": "percentile", + "type": "nominal", + "title": "Percentile" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianStack": "off", + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true, + "legendPosition": "bottom" + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "endpoint", + "yAxisData": [ + "latency" + ], + "xAxisGroup": "percentile", + "xAxisLabel": "Endpoint", + "yAxisLabel": "Latency", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "e81a0ea0-b5fd-4021-8737-2c50997ab7a4", + "x": 2, + "y": 19, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Throughput By Provider", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "throughput_last_30m.p50", + "desc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "tag", + "type": "nominal", + "title": "Endpoint" + }, + "y": { + "field": "throughput_last_30m.p50", + "type": "quantitative", + "title": "Tokens/s" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "tag", + "yAxisData": [ + "throughput_last_30m.p50" + ], + "xAxisGroup": "none", + "xAxisLabel": "Endpoint", + "yAxisLabel": "Tokens/s", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "041f6c43-1bf6-4e38-80bb-ca48e03ab8f0", + "x": 0, + "y": 22, + "w": 4, + "h": 7, + "config": { + "_type": "tile/data-stream", + "title": "Benchmarks Vs Price", + "description": "Higher is better on every axis. Affordability scores price per 1M tokens on a log scale, from 100 at $0.01 or less to 0 at $1,000 or more. Change the ceiling with the Affordability ceiling parameter.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "models": { + "scope": "{{scopes.[Models]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Model]}}" + } + } + }, + "variables": [ + "{{variables.[Model]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "radar", + "encoding": { + "axes": [ + { + "field": "benchmarks.artificial_analysis.intelligence_index", + "type": "quantitative", + "title": "Intelligence Index" + }, + { + "field": "benchmarks.artificial_analysis.coding_index", + "type": "quantitative", + "title": "Coding Index" + }, + { + "field": "benchmarks.artificial_analysis.agentic_index", + "type": "quantitative", + "title": "Agentic Index" + }, + { + "field": "inputAffordability", + "type": "quantitative", + "title": "Input Affordability" + }, + { + "field": "outputAffordability", + "type": "quantitative", + "title": "Output Affordability" + }, + { + "field": "cacheReadAffordability", + "type": "quantitative", + "title": "Cache Read Affordability" + } + ] + }, + "style": { + "legendPosition": "none", + "radarShape": "polygon" + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true, + "columnOrder": [ + "inputPrice", + "outputPrice", + "cacheReadPrice", + "context_length", + "top_provider.max_completion_tokens", + "inputModalities", + "outputModalities", + "benchmarks.artificial_analysis.intelligence_index", + "benchmarks.artificial_analysis.coding_index", + "benchmarks.artificial_analysis.agentic_index", + "knowledge_cutoff", + "created", + "expiration_date" + ], + "hiddenColumns": [ + "id", + "name", + "author", + "canonical_slug", + "permaslug", + "pricing.prompt", + "pricing.completion", + "pricing.input_cache_read", + "inputAffordability", + "outputAffordability", + "cacheReadAffordability", + "architecture.input_modalities", + "architecture.output_modalities" + ] + } + } + } + } + }, + { + "i": "c5b9dd64-17b8-428e-b527-1469545543f8", + "x": 0, + "y": 29, + "w": 4, + "h": 1, + "config": { + "_type": "tile/text", + "title": "", + "description": "", + "visualisation": { + "config": { + "content": "Benchmarks: Artificial Analysis ([artificialanalysis.ai](https://artificialanalysis.ai)), via OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)). \nSession cost: OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)), refreshed weekly. \nLicensed under CC BY 4.0.", + "fontSize": 12, + "align": "left", + "autoSize": true + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/modelComparison.dash.json b/plugins/OpenRouter/v1/defaultContent/modelComparison.dash.json new file mode 100644 index 00000000..28a31dab --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/modelComparison.dash.json @@ -0,0 +1,1505 @@ +{ + "name": "Model Comparison", + "schemaVersion": "1.5", + "timeframe": "last30days", + "variables": [ + "{{variables.[Compared Models]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "23cffe4d-9415-4150-b3ca-18786feac31b", + "x": 0, + "y": 0, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Models", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "SELECT\n s.rawId AS id,\n CASE WHEN s.rawId IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(s.rawId, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' END AS url,\n m.name,\n m.author,\n m.inputPrice,\n m.outputPrice,\n m.cacheReadPrice,\n m.context_length AS contextLength,\n m.\"top_provider.max_completion_tokens\" AS maxCompletionTokens,\n m.inputModalities,\n m.outputModalities,\n m.\"benchmarks.artificial_analysis.intelligence_index\" AS intelligenceIndex,\n m.\"benchmarks.artificial_analysis.coding_index\" AS codingIndex,\n m.\"benchmarks.artificial_analysis.agentic_index\" AS agenticIndex,\n m.knowledge_cutoff AS knowledgeCutoff,\n m.created,\n m.expiration_date AS expirationDate\nFROM Models m\nJOIN Selected s ON m.id = s.rawId\nORDER BY m.name", + "tables": [ + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Selected", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "author", + "displayName": "Author", + "shape": "string" + }, + { + "name": "inputPrice", + "displayName": "Input Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "name": "outputPrice", + "displayName": "Output Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "name": "cacheReadPrice", + "displayName": "Cache Read Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "name": "contextLength", + "displayName": "Context Length", + "shape": "number" + }, + { + "name": "maxCompletionTokens", + "displayName": "Max Completion Tokens", + "shape": "number" + }, + { + "name": "inputModalities", + "displayName": "Input Modalities", + "shape": "string" + }, + { + "name": "outputModalities", + "displayName": "Output Modalities", + "shape": "string" + }, + { + "name": "intelligenceIndex", + "displayName": "Intelligence Index", + "shape": "number" + }, + { + "name": "codingIndex", + "displayName": "Coding Index", + "shape": "number" + }, + { + "name": "agenticIndex", + "displayName": "Agentic Index", + "shape": "number" + }, + { + "name": "knowledgeCutoff", + "displayName": "Knowledge Cutoff", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ] + }, + { + "name": "created", + "displayName": "Created", + "shape": [ + "date", + { + "inputPattern": "t" + } + ] + }, + { + "name": "expirationDate", + "displayName": "Expiration Date", + "shape": [ + "date", + { + "timeZone": "Etc/UTC" + } + ] + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "author", + "inputPrice", + "outputPrice", + "cacheReadPrice", + "contextLength", + "maxCompletionTokens", + "inputModalities", + "outputModalities", + "intelligenceIndex", + "codingIndex", + "agenticIndex", + "knowledgeCutoff", + "created", + "expirationDate" + ], + "hiddenColumns": [ + "id", + "url" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "url", + "title": "Model", + "renderer": { + "type": "link", + "labelField": "name" + } + }, + { + "field": "author", + "title": "Author", + "renderer": { + "type": "text" + } + }, + { + "field": "inputPrice", + "title": "Input Price ($/1M Tokens)", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "outputPrice", + "title": "Output Price ($/1M Tokens)", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "cacheReadPrice", + "title": "Cache Read Price ($/1M Tokens)", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "contextLength", + "title": "Context Length", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "maxCompletionTokens", + "title": "Max Completion Tokens", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "inputModalities", + "title": "Input Modalities", + "renderer": { + "type": "text" + } + }, + { + "field": "outputModalities", + "title": "Output Modalities", + "renderer": { + "type": "text" + } + }, + { + "field": "intelligenceIndex", + "title": "Intelligence Index", + "align": "right", + "renderer": { + "type": "number", + "decimals": 2 + } + }, + { + "field": "codingIndex", + "title": "Coding Index", + "align": "right", + "renderer": { + "type": "number", + "decimals": 2 + } + }, + { + "field": "agenticIndex", + "title": "Agentic Index", + "align": "right", + "renderer": { + "type": "number", + "decimals": 2 + } + } + ] + }, + "style": {} + } + } + } + }, + { + "i": "ea3b78fb-bb19-4538-a408-5d066f96ab52", + "x": 0, + "y": 3, + "w": 2, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Benchmarks Vs Price", + "description": "Higher is better on every axis. Affordability scores price per 1M tokens on a log scale, from 100 at $0.01 or less to 0 at $1,000 or more.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "SELECT\n s.sourceId AS id,\n m.name,\n m.\"benchmarks.artificial_analysis.intelligence_index\" AS intelligenceIndex,\n m.\"benchmarks.artificial_analysis.coding_index\" AS codingIndex,\n m.\"benchmarks.artificial_analysis.agentic_index\" AS agenticIndex,\n m.inputAffordability,\n m.outputAffordability,\n m.cacheReadAffordability\nFROM Models m\nJOIN Selected s ON m.id = s.rawId\nORDER BY m.name", + "tables": [ + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Selected", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "intelligenceIndex", + "displayName": "Intelligence Index", + "shape": "number" + }, + { + "name": "codingIndex", + "displayName": "Coding Index", + "shape": "number" + }, + { + "name": "agenticIndex", + "displayName": "Agentic Index", + "shape": "number" + }, + { + "name": "inputAffordability", + "displayName": "Input Affordability", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "outputAffordability", + "displayName": "Output Affordability", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "cacheReadAffordability", + "displayName": "Cache Read Affordability", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "radar", + "encoding": { + "series": { + "field": "name", + "type": "nominal", + "title": "Model" + }, + "axes": [ + { + "field": "intelligenceIndex", + "type": "quantitative", + "title": "Intelligence Index" + }, + { + "field": "codingIndex", + "type": "quantitative", + "title": "Coding Index" + }, + { + "field": "agenticIndex", + "type": "quantitative", + "title": "Agentic Index" + }, + { + "field": "inputAffordability", + "type": "quantitative", + "title": "Input Affordability" + }, + { + "field": "outputAffordability", + "type": "quantitative", + "title": "Output Affordability" + }, + { + "field": "cacheReadAffordability", + "type": "quantitative", + "title": "Cache Read Affordability" + } + ] + }, + "style": { + "legendPosition": "right", + "radarShape": "polygon", + "radarFill": false, + "radarRadius": 80 + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "hiddenColumns": [ + "id" + ] + } + } + } + } + }, + { + "i": "e8e0ca65-ced6-4265-b2ac-74fea2e224f0", + "x": 2, + "y": 3, + "w": 2, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Artificial Analysis Indices", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n canonical_slug,\n sourceId,\n name\n FROM Selected\n QUALIFY row_number() OVER (PARTITION BY canonical_slug ORDER BY length(sourceId), sourceId) = 1\n)\nSELECT\n s.name,\n b.benchmark,\n b.score\nFROM Benchmarks b\nJOIN by_slug s ON b.model = s.canonical_slug\nWHERE b.source = 'artificial-analysis'\nORDER BY b.benchmark, s.name", + "tables": [ + { + "tableName": "Benchmarks", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[benchmarks]}}", + "name": "benchmarks", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Selected", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "benchmark", + "displayName": "Benchmark", + "shape": "string" + }, + { + "name": "score", + "displayName": "Score", + "shape": [ + "number", + { + "decimalPlaces": 1 + } + ] + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "benchmark", + "yAxisData": [ + "score" + ], + "xAxisGroup": "name", + "xAxisLabel": "", + "yAxisLabel": "Index", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "auto" + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "benchmark", + "type": "nominal", + "title": "Benchmark" + }, + "y": { + "field": "score", + "type": "quantitative", + "title": "Score" + }, + "series": { + "field": "name", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "cartesianStack": "off", + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Index" + } + } + } + } + }, + { + "i": "e4a900b8-db8c-4f61-ab49-a272d80fdd2f", + "x": 0, + "y": 8, + "w": 2, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Design Arena Elo", + "description": "Elo rating by design category. Higher is better.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n canonical_slug,\n sourceId,\n name\n FROM Selected\n QUALIFY row_number() OVER (PARTITION BY canonical_slug ORDER BY length(sourceId), sourceId) = 1\n)\nSELECT\n s.name,\n b.benchmark,\n b.score\nFROM Benchmarks b\nJOIN by_slug s ON b.model = s.canonical_slug\nWHERE b.source = 'design-arena' AND b.metric = 'elo'\nORDER BY b.benchmark, s.name", + "tables": [ + { + "tableName": "Benchmarks", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[benchmarks]}}", + "name": "benchmarks", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Selected", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "benchmark", + "displayName": "Category", + "shape": "string" + }, + { + "name": "score", + "displayName": "Elo", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "benchmark", + "yAxisData": [ + "score" + ], + "xAxisGroup": "name", + "xAxisLabel": "", + "yAxisLabel": "Elo", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "custom", + "maximum": 1600, + "minimum": 900 + } + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "benchmark", + "type": "nominal", + "title": "Category" + }, + "y": { + "field": "score", + "type": "quantitative", + "title": "Elo" + }, + "series": { + "field": "name", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "cartesianStack": "off", + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Elo", + "cartesianYAxisMin": 900, + "cartesianYAxisMax": 1600 + } + } + } + } + }, + { + "i": "4bf8b04e-889d-4518-b96c-491fe668c142", + "x": 2, + "y": 8, + "w": 2, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Session Cost By Harness", + "description": "Median cost of one 10–49 turn coding-agent session, by model and harness.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n permaslug,\n sourceId,\n name\n FROM Selected\n -- Datasets key models by permaslug; a :batch model shares its base's, so keep one\n QUALIFY row_number() OVER (PARTITION BY permaslug ORDER BY length(sourceId), sourceId) = 1\n)\nSELECT\n s.name,\n c.app_name AS harness,\n c.median_session_cost_usd AS cost\nFROM SessionCost c\nJOIN by_slug s ON c.model_permaslug = s.permaslug\nWHERE c.turn_range = '10-49-turns'\nORDER BY s.name, c.app_name", + "tables": [ + { + "tableName": "SessionCost", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionCost]}}", + "name": "sessionCost", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Selected", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "harness", + "displayName": "Harness", + "shape": "string" + }, + { + "name": "cost", + "displayName": "Median Session Cost", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 4 + } + ] + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scatter", + "encoding": { + "x": { + "field": "name", + "type": "nominal", + "title": "Model" + }, + "y": { + "field": "cost", + "type": "quantitative", + "title": "Median Session Cost ($)" + }, + "color": { + "field": "harness", + "type": "nominal", + "title": "Harness" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianYAxisScale": "log", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Median Session Cost ($, log scale)", + "cartesianShowVerticalGridLines": true, + "cartesianXAxisLabelRotation": 45, + "cartesianXAxisTickDensity": "dense" + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": {} + } + } + } + }, + { + "i": "2c1f928b-b7a2-48d2-ac16-e100b0f74f21", + "x": 0, + "y": 13, + "w": 4, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "OpenRouter Evals", + "description": "Results from OpenRouter's own evals. The metric differs by benchmark, so scores aren't comparable across rows.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n canonical_slug,\n sourceId,\n rawId,\n name\n FROM Selected\n QUALIFY row_number() OVER (PARTITION BY canonical_slug ORDER BY length(sourceId), sourceId) = 1\n)\nSELECT\n s.rawId AS id,\n CASE WHEN s.rawId IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(s.rawId, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' END AS url,\n s.name,\n b.benchmark,\n b.metric,\n b.score,\n b.tasks,\n b.avgCostPerTask,\n b.avgDurationMs\nFROM Benchmarks b\nJOIN by_slug s ON b.model = s.canonical_slug\nWHERE b.source = 'openrouter'\nORDER BY b.score DESC", + "tables": [ + { + "tableName": "Benchmarks", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[benchmarks]}}", + "name": "benchmarks", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Selected", + "config": { + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "benchmark", + "displayName": "Benchmark", + "shape": "string" + }, + { + "name": "metric", + "displayName": "Metric", + "shape": "string" + }, + { + "name": "score", + "displayName": "Score", + "shape": [ + "number", + { + "decimalPlaces": 2 + } + ] + }, + { + "name": "tasks", + "displayName": "Tasks", + "shape": "number" + }, + { + "name": "avgCostPerTask", + "displayName": "Avg Cost per Task", + "shape": "usd" + }, + { + "name": "avgDurationMs", + "displayName": "Avg Duration", + "shape": "milliseconds" + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "benchmark", + "metric", + "score", + "tasks", + "avgCostPerTask", + "avgDurationMs" + ], + "hiddenColumns": [ + "id", + "url" + ] + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "url", + "title": "Model", + "renderer": { + "type": "link", + "labelField": "name" + } + }, + { + "field": "benchmark", + "title": "Benchmark", + "renderer": { + "type": "text" + } + }, + { + "field": "metric", + "title": "Metric", + "renderer": { + "type": "text" + } + }, + { + "field": "score", + "title": "Score", + "align": "right", + "renderer": { + "type": "number", + "decimals": 2 + } + }, + { + "field": "tasks", + "title": "Tasks", + "align": "right", + "renderer": { + "type": "number", + "decimals": 0 + } + }, + { + "field": "avgCostPerTask", + "title": "Avg Cost per Task", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "avgDurationMs", + "title": "Avg Duration", + "align": "right", + "renderer": { + "type": "number", + "decimals": 0 + } + } + ] + }, + "style": {} + } + } + } + }, + { + "i": "f835faa9-edd8-4bbb-8f89-659d4eadd362", + "x": 0, + "y": 17, + "w": 2, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Throughput By Provider", + "description": "Median tokens per second over the last 30 minutes.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "throughput_last_30m.p50", + "desc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "tag", + "yAxisData": [ + "throughput_last_30m.p50" + ], + "xAxisGroup": "model_name", + "xAxisLabel": "Endpoint", + "yAxisLabel": "Tokens/s", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "88a7859f-3bb2-42ba-9a83-9beaaae99d05", + "x": 2, + "y": 17, + "w": 2, + "h": 5, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Latency By Provider", + "description": "Median latency over the last 30 minutes.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[modelProviders]}}", + "name": "modelProviders", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "latency_last_30m.p50", + "asc" + ] + ] + } + }, + "scope": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "tag", + "yAxisData": [ + "latency_last_30m.p50" + ], + "xAxisGroup": "model_name", + "xAxisLabel": "Endpoint", + "yAxisLabel": "Latency (ms)", + "showXAxisLabel": false, + "showYAxisLabel": true, + "showLegend": true, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "vertical", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": true, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "cd3d1575-854e-4b32-bdf0-501ddf31ae99", + "x": 0, + "y": 22, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Spend (Last 30 Days)", + "description": "Your own spend on each model through your OpenRouter account.", + "timeframe": "last30days", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model", + "filterObjects": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "group", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + }, + "series": { + "field": "group", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)" + } + } + } + } + }, + { + "i": "97618c1f-a773-45f4-bba5-ccd2afa7526a", + "x": 2, + "y": 22, + "w": 2, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Cost Per 1M Tokens (Last 30 Days)", + "description": "Your own cost per million tokens on each model.", + "timeframe": "last30days", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model", + "filterObjects": { + "scope": "{{scopes.[Model Comparison]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Compared Models]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "cost_per_million_tokens", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 4 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Compared Models]}}" + ], + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "cost_per_million_tokens" + ], + "seriesColumn": "group", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Cost per 1M tokens ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "cost_per_million_tokens", + "type": "quantitative", + "title": "Cost per 1M tokens ($)" + }, + "series": { + "field": "group", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Cost per 1M tokens ($)" + } + } + } + } + }, + { + "i": "e26858ee-6975-4e02-b7ee-c8b2b46614b0", + "x": 0, + "y": 26, + "w": 4, + "h": 1, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/text", + "title": "", + "description": "", + "visualisation": { + "config": { + "content": "Benchmarks: Artificial Analysis ([artificialanalysis.ai](https://artificialanalysis.ai)), Design Arena ([www.designarena.ai](https://www.designarena.ai)), and OpenRouter evals ([openrouter.ai](https://openrouter.ai)), via OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)). \nSession cost: OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)), refreshed weekly. \nLicensed under CC BY 4.0.", + "fontSize": 12, + "align": "left", + "autoSize": true + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/modelLeaderboards.dash.json b/plugins/OpenRouter/v1/defaultContent/modelLeaderboards.dash.json new file mode 100644 index 00000000..bdc16f6b --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/modelLeaderboards.dash.json @@ -0,0 +1,1363 @@ +{ + "name": "Model Leaderboards", + "schemaVersion": "1.5", + "timeframe": "last30days", + "dashboard": { + "_type": "layout/grid", + "columns": 6, + "version": 1, + "contents": [ + { + "i": "0c4d2c18-8f65-42e2-9a44-cdd6c0efe180", + "x": 0, + "y": 0, + "w": 4, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Top Models On OpenRouter (This Month)", + "description": "Top 10 models by tokens so far this month, compared with the same days of last month. Rank change is against last month's ranking over those days.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "-- Month to date vs the same days of last month: last month only counts days up to\n-- the latest day this month has data for, so a partial month compares like for like.\n-- Dates arrive as ISO strings (YYYY-MM-DD...), so month and day are sliced from the text.\n-- Timeframe edges are local time but dates are UTC, so each table can spill a day into the\n-- neighbouring month. Last month is the month most of LastMonth's rows fall in (it is never\n-- empty, unlike ThisMonth on the 1st), and this month is the one after it.\nWITH days AS (\n SELECT 'this' AS source, CAST(date AS VARCHAR) AS day, model_permaslug AS slug, total_tokens\n FROM ThisMonth\n WHERE model_permaslug <> 'other'\n UNION ALL\n SELECT 'last' AS source, CAST(date AS VARCHAR) AS day, model_permaslug AS slug, total_tokens\n FROM LastMonth\n WHERE model_permaslug <> 'other'\n),\nprevious AS (\n SELECT mode(substr(day, 1, 7)) AS previous_month\n FROM days\n WHERE source = 'last'\n),\nmonths AS (\n SELECT\n strftime(CAST(previous_month || '-01' AS DATE) + INTERVAL 1 MONTH, '%Y-%m') AS month,\n previous_month\n FROM previous\n),\ncutoff AS (\n SELECT\n m.month,\n m.previous_month,\n (SELECT max(CAST(substr(day, 9, 2) AS INTEGER)) FROM days WHERE source = 'this' AND substr(day, 1, 7) = m.month) AS last_day\n FROM months m\n),\nthis_month AS (\n SELECT d.slug, sum(d.total_tokens) AS tokens\n FROM days d, cutoff\n WHERE d.source = 'this' AND substr(d.day, 1, 7) = cutoff.month\n GROUP BY d.slug\n),\nlast_month AS (\n SELECT\n d.slug,\n sum(d.total_tokens) AS tokens,\n row_number() OVER (ORDER BY sum(d.total_tokens) DESC) AS rank\n FROM days d, cutoff\n WHERE d.source = 'last'\n AND substr(d.day, 1, 7) = cutoff.previous_month\n AND CAST(substr(d.day, 9, 2) AS INTEGER) <= cutoff.last_day\n GROUP BY d.slug\n),\nranked AS (\n SELECT\n slug,\n tokens,\n row_number() OVER (ORDER BY tokens DESC) AS rank\n FROM this_month\n),\nby_slug AS (\n SELECT\n permaslug AS slug,\n id,\n name\n FROM Models\n -- Datasets key models by permaslug; a :batch model shares its base's, so keep one\n QUALIFY row_number() OVER (PARTITION BY permaslug ORDER BY length(id), id) = 1\n)\nSELECT\n r.rank,\n m.id,\n -- Models missing from the models stream (e.g. stealth models) link to their OpenRouter page\n CASE WHEN m.id IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(m.id, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' ELSE 'https://openrouter.ai/' || r.slug END AS url,\n COALESCE(m.name, r.slug) AS name,\n r.tokens,\n l.tokens AS lastTokens,\n (r.tokens - l.tokens) / l.tokens AS change,\n COALESCE('#' || CAST(l.rank AS VARCHAR), 'New') AS lastRank,\n l.rank - r.rank AS rankChange\nFROM ranked r\nLEFT JOIN last_month l ON l.slug = r.slug\nLEFT JOIN by_slug m ON m.slug = r.slug\nWHERE r.rank <= 10\nORDER BY r.rank", + "tables": [ + { + "tableName": "ThisMonth", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[rankings]}}", + "name": "rankings", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "period": "day" + } + }, + "timeframe": "thisMonth" + } + }, + { + "tableName": "LastMonth", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[rankings]}}", + "name": "rankings", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "period": "day" + } + }, + "timeframe": "lastMonth" + } + }, + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "rank", + "displayName": "Rank", + "shape": "number" + }, + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "tokens", + "displayName": "Tokens (This Month)", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "name": "lastTokens", + "displayName": "Same Days Last Month", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "name": "change", + "displayName": "Token Change", + "shape": [ + "percent", + { + "asZeroToOne": true, + "decimalPlaces": 0 + } + ] + }, + { + "name": "lastRank", + "displayName": "Last Month Rank", + "shape": "string" + }, + { + "name": "rankChange", + "displayName": "Rank Change", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "rank", + "title": "#", + "align": "right", + "width": 50, + "renderer": { + "type": "number", + "decimals": 0 + } + }, + { + "field": "url", + "title": "Model", + "renderer": { + "type": "link", + "labelField": "name" + } + }, + { + "field": "tokens", + "title": "Tokens (This Month)", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "lastTokens", + "title": "Same Days Last Month", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "change", + "title": "Token Change", + "align": "right", + "renderer": { + "type": "delta" + } + }, + { + "field": "lastRank", + "title": "Last Month Rank", + "align": "center", + "renderer": { + "type": "badge", + "colors": { + "New": "rgba(22, 163, 74, 0.55)" + }, + "defaultColor": "rgba(71, 85, 105, 0.5)" + } + }, + { + "field": "rankChange", + "title": "Rank Change", + "align": "right", + "renderer": { + "type": "delta" + } + } + ] + }, + "style": {} + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "rank", + "name", + "tokens", + "lastTokens", + "change", + "lastRank", + "rankChange" + ], + "hiddenColumns": [ + "id", + "url" + ] + } + } + } + } + }, + { + "i": "1e2875d1-b28b-4f04-ab27-47b78899619d", + "x": 0, + "y": 4, + "w": 6, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Intelligence Index Vs Input Price (Top 20)", + "description": "Top 20 models by Artificial Analysis Intelligence Index, against their input price. Higher and further left is better value.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n id,\n name AS model,\n author,\n inputPrice,\n \"benchmarks.artificial_analysis.intelligence_index\" AS intelligence\n FROM Models\n WHERE \"benchmarks.artificial_analysis.intelligence_index\" IS NOT NULL\n AND inputPrice IS NOT NULL\n QUALIFY row_number() OVER (PARTITION BY canonical_slug ORDER BY length(id), id) = 1\n)\nSELECT\n id,\n model,\n '/drilldown/node?sourceId=Model%2F' || replace(replace(id, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' AS url,\n author,\n inputPrice,\n intelligence\nFROM by_slug\nORDER BY intelligence DESC\nLIMIT 20", + "tables": [ + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "model", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "url", + "displayName": "Link", + "shape": [ + "url", + { + "label": "Model page" + } + ] + }, + { + "name": "author", + "displayName": "Author", + "shape": "string" + }, + { + "name": "inputPrice", + "displayName": "Input Price ($/1M Tokens)", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "name": "intelligence", + "displayName": "Intelligence Index", + "shape": [ + "number", + { + "decimalPlaces": 1 + } + ] + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scatter", + "encoding": { + "x": { + "field": "inputPrice", + "type": "quantitative", + "title": "Input Price ($/1M Tokens)" + }, + "y": { + "field": "intelligence", + "type": "quantitative", + "title": "Intelligence Index" + }, + "color": { + "field": "author", + "type": "nominal", + "title": "Author" + } + }, + "style": { + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true, + "cartesianYAxisRangeMode": "fit", + "cartesianPointRadius": 7, + "cartesianShowVerticalGridLines": true, + "legendPosition": "bottom", + "cartesianTooltipTemplate": "{{{{raw}}}}{{model}}: {{value}}{{{{/raw}}}}" + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "model", + "url", + "author", + "inputPrice", + "intelligence" + ], + "hiddenColumns": [ + "id" + ] + } + } + } + } + }, + { + "i": "3eec66c4-de77-40ee-b403-37620ac6ec6b", + "x": 0, + "y": 8, + "w": 3, + "h": 3, + "config": { + "_type": "tile/data-stream", + "title": "Top GPQA Models By Accuracy And Cost", + "description": "Top 15 models by accuracy on GPQA Diamond, graduate-level science questions that can't be answered by searching.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n permaslug AS slug,\n id,\n name\n FROM Models\n -- Datasets key models by permaslug; a :batch model shares its base's, so keep one\n QUALIFY row_number() OVER (PARTITION BY permaslug ORDER BY length(id), id) = 1\n)\nSELECT\n row_number() OVER (ORDER BY b.score DESC) AS rank,\n m.id,\n -- Models missing from the models stream (e.g. stealth models) link to their OpenRouter page\n CASE WHEN m.id IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(m.id, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' ELSE 'https://openrouter.ai/' || b.model END AS url,\n COALESCE(m.name, b.modelName) AS model,\n b.score AS accuracy,\n b.avgCostPerTask\nFROM Benchmarks b\nLEFT JOIN by_slug m ON m.slug = b.model\nWHERE b.benchmark = 'gpqa_diamond' AND b.metric = 'accuracy'\nORDER BY b.score DESC\nLIMIT 15", + "tables": [ + { + "tableName": "Benchmarks", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[benchmarks]}}", + "name": "benchmarks", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "source": "openrouter" + } + }, + "timeframe": "none" + } + }, + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "rank", + "displayName": "Rank", + "shape": "number" + }, + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "model", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "accuracy", + "displayName": "Accuracy", + "shape": [ + "percent", + { + "asZeroToOne": true, + "decimalPlaces": 1 + } + ] + }, + { + "name": "avgCostPerTask", + "displayName": "Avg Cost Per Task", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 3 + } + ] + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "rank", + "title": "#", + "align": "right", + "width": 40, + "renderer": { + "type": "number", + "decimals": 0 + } + }, + { + "field": "url", + "title": "Model", + "width": 240, + "renderer": { + "type": "link", + "labelField": "model" + } + }, + { + "field": "accuracy", + "title": "Accuracy", + "align": "right", + "width": 110, + "renderer": { + "type": "text" + } + }, + { + "field": "avgCostPerTask", + "title": "Avg Cost Per Task", + "renderer": { + "type": "bar" + } + } + ] + }, + "style": {} + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "rank", + "model", + "accuracy", + "avgCostPerTask" + ], + "hiddenColumns": [ + "id", + "url" + ] + } + } + } + } + }, + { + "i": "df0c3dda-bfa5-48a0-babf-ed96590b4be2", + "x": 3, + "y": 8, + "w": 3, + "h": 3, + "config": { + "_type": "tile/data-stream", + "title": "Top Models For Website Design", + "description": "Top 15 models by Elo rating on Design Arena's website arena, from head-to-head votes. Win rate is how often voters picked the model's site.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "WITH by_slug AS (\n SELECT\n permaslug AS slug,\n id\n FROM Models\n -- Datasets key models by permaslug; a :batch model shares its base's, so keep one\n QUALIFY row_number() OVER (PARTITION BY permaslug ORDER BY length(id), id) = 1\n)\n-- Design Arena's own names keep reasoning-effort variants apart (e.g. \"(xhigh)\", \"Max\")\nSELECT\n row_number() OVER (ORDER BY b.score DESC) AS rank,\n m.id,\n -- Models missing from the models stream (e.g. stealth models) link to their OpenRouter page\n CASE WHEN m.id IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(m.id, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' ELSE 'https://openrouter.ai/' || b.model END AS url,\n b.modelName AS model,\n b.score AS elo,\n b.winRate,\n b.avgDurationMs\nFROM Benchmarks b\nLEFT JOIN by_slug m ON m.slug = b.model\nWHERE b.benchmark = 'website' AND b.metric = 'elo'\nORDER BY b.score DESC\nLIMIT 15", + "tables": [ + { + "tableName": "Benchmarks", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[benchmarks]}}", + "name": "benchmarks", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "source": "design-arena" + } + }, + "timeframe": "none" + } + }, + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "rank", + "displayName": "Rank", + "shape": "number" + }, + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "model", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "elo", + "displayName": "Elo", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "winRate", + "displayName": "Win Rate", + "shape": [ + "percent", + { + "decimalPlaces": 1 + } + ] + }, + { + "name": "avgDurationMs", + "displayName": "Avg Build Time", + "shape": "milliseconds" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "rank", + "title": "#", + "align": "right", + "width": 40, + "renderer": { + "type": "number", + "decimals": 0 + } + }, + { + "field": "url", + "title": "Model", + "width": 240, + "renderer": { + "type": "link", + "labelField": "model" + } + }, + { + "field": "elo", + "title": "Elo", + "align": "right", + "width": 80, + "renderer": { + "type": "text" + } + }, + { + "field": "winRate", + "title": "Win Rate", + "align": "right", + "width": 100, + "renderer": { + "type": "text" + } + }, + { + "field": "avgDurationMs", + "title": "Avg Build Time", + "renderer": { + "type": "bar" + } + } + ] + }, + "style": {} + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "rank", + "model", + "elo", + "winRate", + "avgDurationMs" + ], + "hiddenColumns": [ + "id", + "url" + ] + } + } + } + } + }, + { + "i": "22bac160-9e66-4597-b230-270811258056", + "x": 4, + "y": 0, + "w": 2, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "OpenRouter Token Share By Author (This Month)", + "description": "", + "timeframe": "thisMonth", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[rankings]}}", + "name": "rankings", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "model_permaslug", + "operation": "notequals", + "value": "other" + } + ] + }, + "group": { + "by": [ + [ + "author", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_tokens" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_tokens_sum", + "desc" + ] + ] + }, + "metadata": [ + { + "name": "total_tokens_sum", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "author_uniqueValues", + "type": "nominal", + "title": "Author" + }, + "value": { + "field": "total_tokens_sum", + "type": "quantitative", + "title": "Tokens" + } + }, + "style": { + "pieInnerRadius": 55, + "pieDonutCenterValue": "total", + "pieLegendStyle": "table" + } + } + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "total_tokens_sum", + "labelColumn": "author_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + } + } + }, + { + "i": "071c926f-0d3c-4192-962f-d191aa03dcbc", + "x": 0, + "y": 11, + "w": 6, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Top Models On OpenRouter By Week (This Year)", + "description": "Each week's 20 most used models across OpenRouter, by tokens. All other models in that week are combined into Other.", + "timeframe": "thisYear", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[rankings]}}", + "name": "rankings", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "period": "week", + "top": 20 + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Week" + }, + "y": { + "field": "total_tokens", + "type": "quantitative", + "aggregate": "sum", + "title": "Tokens" + }, + "series": { + "field": "model_permaslug", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "cartesianStack": "on", + "legendPosition": "bottom" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_tokens" + ], + "seriesColumn": "model_permaslug", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Tokens", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "a3384d79-77a8-49c0-bb08-62d6744303e1", + "x": 0, + "y": 15, + "w": 6, + "h": 4, + "config": { + "_type": "tile/data-stream", + "title": "Task Leaders", + "description": "Models that are the most used model for at least one task on OpenRouter over the last 7 days, with the tasks they lead.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "-- One row per model that is the most used model for at least one task\nWITH leaders AS (\n SELECT\n topModel AS slug,\n count(*) AS tasksLed,\n string_agg(DISTINCT category, ', ' ORDER BY category) AS categories,\n string_agg(task, ', ' ORDER BY usageShare DESC) AS leads,\n sum(usageShare) AS requestShare\n FROM Tasks\n WHERE topModel IS NOT NULL\n GROUP BY topModel\n),\nby_slug AS (\n SELECT\n permaslug AS slug,\n id,\n name\n FROM Models\n -- Datasets key models by permaslug; a :batch model shares its base's, so keep one\n QUALIFY row_number() OVER (PARTITION BY permaslug ORDER BY length(id), id) = 1\n)\nSELECT\n row_number() OVER (ORDER BY l.tasksLed DESC, l.requestShare DESC) AS rank,\n m.id,\n -- Models missing from the models stream (e.g. stealth models) link to their OpenRouter page\n CASE WHEN m.id IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(m.id, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' ELSE 'https://openrouter.ai/' || l.slug END AS url,\n COALESCE(m.name, l.slug) AS model,\n l.tasksLed,\n l.categories,\n l.leads\nFROM leaders l\nLEFT JOIN by_slug m ON m.slug = l.slug\nORDER BY rank", + "tables": [ + { + "tableName": "Tasks", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[taskClassifications]}}", + "name": "taskClassifications", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + }, + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "rank", + "displayName": "Rank", + "shape": "number" + }, + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "model", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "tasksLed", + "displayName": "Tasks Led", + "shape": [ + "number", + { + "decimalPlaces": 0 + } + ] + }, + { + "name": "categories", + "displayName": "Categories", + "shape": "string" + }, + { + "name": "leads", + "displayName": "Leads (Busiest First)", + "shape": "string" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "rank", + "title": "#", + "align": "right", + "width": 40, + "renderer": { + "type": "number", + "decimals": 0 + } + }, + { + "field": "url", + "title": "Model", + "width": 260, + "renderer": { + "type": "link", + "labelField": "model" + } + }, + { + "field": "tasksLed", + "title": "Tasks Led", + "align": "right", + "width": 90, + "renderer": { + "type": "number", + "decimals": 0 + } + }, + { + "field": "categories", + "title": "Categories", + "width": 260, + "renderer": { + "type": "tag-list" + } + }, + { + "field": "leads", + "title": "Leads (Busiest First)", + "renderer": { + "type": "text" + } + } + ] + }, + "style": { + "richTableWrapText": true + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "rank", + "model", + "tasksLed", + "categories", + "leads" + ], + "hiddenColumns": [ + "id", + "url" + ] + } + } + } + } + }, + { + "i": "37f6bcdf-02a2-4c2a-861d-c9515d1c2092", + "x": 0, + "y": 19, + "w": 6, + "h": 8, + "config": { + "_type": "tile/data-stream", + "title": "Claude Code Cost Per Session", + "description": "Median cost of one Claude Code session routed through OpenRouter, by model and session length. Users can pick any model on OpenRouter, so many aren't Anthropic's.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[sessionCost]}}", + "name": "sessionCost", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "harness": "claude-code" + }, + "sort": { + "by": [ + [ + "sessionLengthOrder", + "asc" + ], + [ + "median_session_cost_usd", + "asc" + ] + ] + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scatter", + "encoding": { + "x": { + "field": "model_permaslug", + "type": "nominal", + "title": "Model" + }, + "y": { + "field": "median_session_cost_usd", + "type": "quantitative", + "title": "Median Session Cost ($)" + }, + "color": { + "field": "sessionLength", + "type": "nominal", + "title": "Session Length" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianYAxisScale": "log", + "cartesianXAxisLabelRotation": 45, + "cartesianXAxisTickDensity": "dense", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Median Session Cost ($, log scale)", + "cartesianShowVerticalGridLines": true + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "model_permaslug", + "sessionLength", + "median_session_cost_usd", + "app_name" + ], + "hiddenColumns": [ + "app_slug", + "turn_range", + "sessionLengthOrder", + "asOf", + "citation" + ] + } + } + } + } + }, + { + "i": "56d4d9f8-9cc4-4852-9306-2997d9e87000", + "x": 0, + "y": 27, + "w": 6, + "h": 8, + "config": { + "_type": "tile/data-stream", + "title": "Top Agentic Models Compared", + "description": "Higher is better on every axis. Affordability scores price per 1M tokens on a log scale, from 100 at $0.01 or less to 0 at $1,000 or more. Change the ceiling with the Affordability ceiling parameter.", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}", + "filter": { + "multiOperation": "and", + "filters": [ + { + "column": "benchmarks.artificial_analysis.agentic_index", + "operation": "greaterthan", + "value": "0" + }, + { + "column": "benchmarks.artificial_analysis.intelligence_index", + "operation": "greaterthan", + "value": "0" + }, + { + "column": "benchmarks.artificial_analysis.coding_index", + "operation": "greaterthan", + "value": "0" + }, + { + "column": "name", + "operation": "notcontains", + "value": "(batch)" + }, + { + "column": "name", + "operation": "notcontains", + "value": "(free)" + } + ] + }, + "sort": { + "by": [ + [ + "benchmarks.artificial_analysis.agentic_index", + "desc" + ], + [ + "benchmarks.artificial_analysis.intelligence_index", + "desc" + ], + [ + "benchmarks.artificial_analysis.coding_index", + "desc" + ] + ], + "top": 10 + } + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "radar", + "encoding": { + "series": { + "field": "name", + "type": "nominal", + "title": "Model" + }, + "axes": [ + { + "field": "benchmarks.artificial_analysis.intelligence_index", + "type": "quantitative", + "title": "Intelligence Index" + }, + { + "field": "benchmarks.artificial_analysis.coding_index", + "type": "quantitative", + "title": "Coding Index" + }, + { + "field": "benchmarks.artificial_analysis.agentic_index", + "type": "quantitative", + "title": "Agentic Index" + }, + { + "field": "inputAffordability", + "type": "quantitative", + "title": "Input Affordability" + }, + { + "field": "outputAffordability", + "type": "quantitative", + "title": "Output Affordability" + }, + { + "field": "cacheReadAffordability", + "type": "quantitative", + "title": "Cache Read Affordability" + } + ] + }, + "style": { + "legendPosition": "right", + "radarShape": "polygon", + "radarFill": false, + "radarRadius": 80 + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "columnOrder": [ + "name", + "author", + "benchmarks.artificial_analysis.intelligence_index", + "benchmarks.artificial_analysis.coding_index", + "benchmarks.artificial_analysis.agentic_index", + "inputPrice", + "outputPrice", + "cacheReadPrice" + ], + "hiddenColumns": [ + "id", + "canonical_slug", + "permaslug", + "cacheReadPrice", + "top_provider.max_completion_tokens", + "inputModalities", + "outputModalities", + "knowledge_cutoff", + "created", + "expiration_date", + "pricing.prompt", + "pricing.completion", + "pricing.input_cache_read", + "inputAffordability", + "outputAffordability", + "cacheReadAffordability", + "architecture.input_modalities", + "architecture.output_modalities" + ] + } + } + } + } + }, + { + "i": "679f0166-77c4-47c1-9ae5-7e4c1721f718", + "x": 0, + "y": 35, + "w": 6, + "h": 1, + "config": { + "_type": "tile/text", + "title": "", + "description": "", + "visualisation": { + "config": { + "content": "Benchmarks: Artificial Analysis ([artificialanalysis.ai](https://artificialanalysis.ai)), Design Arena ([www.designarena.ai](https://www.designarena.ai)), and OpenRouter evals ([openrouter.ai](https://openrouter.ai)), via OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)). \nRankings, tasks, and session cost: OpenRouter ([openrouter.ai/rankings](https://openrouter.ai/rankings)). Tasks cover the 7 days to yesterday (UTC); session cost is refreshed weekly. \nLicensed under CC BY 4.0.", + "fontSize": 12, + "align": "left", + "autoSize": true + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/overview.dash.json b/plugins/OpenRouter/v1/defaultContent/overview.dash.json new file mode 100644 index 00000000..42a28668 --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/overview.dash.json @@ -0,0 +1,1291 @@ +{ + "name": "Overview", + "schemaVersion": "1.5", + "timeframe": "last30days", + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "bb7e5c59-ac7d-4c28-9966-a72354c327b2", + "x": 0, + "y": 0, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[credits]}}", + "name": "credits", + "pluginConfigId": "{{configId}}" + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "gauge", + "encoding": { + "value": { + "field": "remaining", + "type": "quantitative", + "title": "Credits Remaining" + }, + "max": { + "field": "total_credits", + "type": "quantitative", + "title": "Total Credits" + } + }, + "style": { + "gaugeLabelText": "Credits Remaining", + "gaugeAxisLabels": true, + "gaugeBands": [ + { + "to": 0.1, + "color": "#ee6666" + }, + { + "to": 0.25, + "color": "#fac858" + }, + { + "to": 1, + "color": "#91cc75" + } + ] + } + } + }, + "visualisation": { + "type": "data-stream-gauge", + "config": { + "data-stream-gauge": { + "value": { + "type": "mean", + "columns": [ + "remaining" + ] + }, + "label": "Credits Remaining", + "minimum": 0, + "maximumColumn": "total_credits" + } + } + } + } + }, + { + "i": "6143e7be-4b44-4ff1-804c-ada7021bd6d6", + "x": 2, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "", + "description": "", + "timeframe": "thisMonth", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": {}, + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend (This Month)" + } + ] + }, + "style": { + "scalarLabelText": "Spend (This Month)" + } + } + }, + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "total_usage_sum", + "comparisonColumn": "none", + "label": "Spend (This Month)" + } + } + } + } + }, + { + "i": "d77eec0c-ba8b-48a5-a65d-86fcac004f4d", + "x": 3, + "y": 0, + "w": 1, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "", + "description": "", + "timeframe": "thisMonth", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": {}, + "group": { + "by": [], + "aggregate": [ + { + "type": "sum", + "names": [ + "request_count" + ] + } + ] + }, + "metadata": [ + { + "name": "request_count_sum", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "scalar", + "encoding": { + "values": [ + { + "field": "request_count_sum", + "type": "quantitative", + "title": "Requests (This Month)" + } + ] + }, + "style": { + "scalarLabelText": "Requests (This Month)" + } + } + }, + "visualisation": { + "type": "data-stream-scalar", + "config": { + "data-stream-scalar": { + "value": "request_count_sum", + "comparisonColumn": "none", + "label": "Requests (This Month)" + } + } + } + } + }, + { + "i": "63530d85-be7f-4e7e-bd5f-645da0d4bb6e", + "x": 0, + "y": 2, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": {}, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "86f14850-5e5d-40dc-83ed-e0cf5b90684a", + "x": 2, + "y": 2, + "w": 2, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Requests Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": {}, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "request_count", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "request_count", + "type": "quantitative", + "title": "Requests" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Requests", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "request_count" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Requests", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "89d9ae8b-e700-4c31-813a-8380d9511fbb", + "x": 0, + "y": 4, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Model Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model" + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "aggregate": "sum", + "title": "Spend ($)" + }, + "series": { + "field": "group", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "cartesianStack": "on", + "legendPosition": "bottom" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "group", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "c6b79b6d-a751-4eaa-ac22-7721b5dfba27", + "x": 0, + "y": 7, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Model Usage", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "datastream-sql", + "dataSourceConfig": { + "version": "2.0", + "sql": "-- Usage arrives per model per time bucket; total each model over the timeframe\nWITH usage_by_model AS (\n SELECT\n \"group\" AS slug,\n sum(total_usage) AS spend,\n sum(request_count) AS requests,\n sum(tokens_prompt) AS promptTokens,\n sum(tokens_completion) AS completionTokens\n FROM Usage\n GROUP BY \"group\"\n),\nby_slug AS (\n SELECT\n canonical_slug AS slug,\n id,\n name\n FROM Models\n QUALIFY row_number() OVER (PARTITION BY canonical_slug ORDER BY length(id), id) = 1\n)\nSELECT\n m.id,\n -- Models missing from the models stream (e.g. stealth models) link to their OpenRouter page\n CASE WHEN m.id IS NOT NULL THEN '/drilldown/node?sourceId=Model%2F' || replace(replace(m.id, '/', '%2F'), ':', '%3A') || '&__configId={{configId}}' ELSE 'https://openrouter.ai/' || u.slug END AS url,\n COALESCE(m.name, u.slug) AS name,\n u.slug,\n u.spend,\n u.requests,\n u.spend / NULLIF(u.requests, 0) AS costPerRequest,\n u.promptTokens,\n u.completionTokens\nFROM usage_by_model u\nLEFT JOIN by_slug m ON m.slug = u.slug\nORDER BY u.spend DESC", + "tables": [ + { + "tableName": "Usage", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model" + } + } + } + }, + { + "tableName": "Models", + "config": { + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[models]}}", + "name": "models", + "pluginConfigId": "{{configId}}" + }, + "timeframe": "none" + } + } + ] + }, + "metadata": [ + { + "name": "id", + "displayName": "Model ID", + "shape": "string", + "visible": false + }, + { + "name": "url", + "displayName": "Model Link", + "shape": "string", + "visible": false + }, + { + "name": "name", + "displayName": "Model", + "shape": "string", + "role": "label" + }, + { + "name": "slug", + "displayName": "Model Slug", + "shape": "string", + "visible": false + }, + { + "name": "spend", + "displayName": "Spend", + "shape": "usd", + "role": "value" + }, + { + "name": "requests", + "displayName": "Requests", + "shape": "number" + }, + { + "name": "costPerRequest", + "displayName": "Cost Per Request", + "shape": [ + "usd", + { + "decimalPlaces": 6 + } + ] + }, + { + "name": "promptTokens", + "displayName": "Prompt Tokens", + "shape": "number" + }, + { + "name": "completionTokens", + "displayName": "Completion Tokens", + "shape": "number" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "url", + "title": "Model", + "renderer": { + "type": "link", + "labelField": "name" + } + }, + { + "field": "spend", + "title": "Spend", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "requests", + "title": "Requests", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "costPerRequest", + "title": "Cost Per Request", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "promptTokens", + "title": "Prompt Tokens", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + }, + { + "field": "completionTokens", + "title": "Completion Tokens", + "align": "right", + "renderer": { + "type": "number", + "compact": true + } + } + ] + }, + "style": {} + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "spend", + "requests", + "costPerRequest", + "promptTokens", + "completionTokens" + ], + "hiddenColumns": [ + "id", + "slug", + "url" + ] + } + } + } + } + }, + { + "i": "55c667d9-63af-4556-962d-87a6325df855", + "x": 0, + "y": 10, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Model", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model" + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "Model" + }, + "y": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "group_uniqueValues", + "yAxisData": [ + "total_usage_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "Model", + "yAxisLabel": "Spend ($)", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "7c94001a-4946-45e0-8d08-08f2b89153ef", + "x": 2, + "y": 10, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Workspace", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "workspace" + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "Workspace" + }, + "value": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "pieInnerRadius": 55, + "pieDonutCenterValue": "total", + "pieLegendStyle": "table" + } + } + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "total_usage_sum", + "labelColumn": "group_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + } + } + }, + { + "i": "da913ee7-05b2-4ce2-b11a-64b91f9d1537", + "x": 0, + "y": 13, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Provider (Last 30 Days)", + "description": "", + "timeframe": "last30days", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "provider" + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "Provider" + }, + "value": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "pieInnerRadius": 55, + "pieDonutCenterValue": "total", + "pieLegendStyle": "table" + } + } + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "total_usage_sum", + "labelColumn": "group_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + } + } + }, + { + "i": "3bf76eb4-561e-4bae-a971-ba12c6c6d216", + "x": 2, + "y": 13, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Latency p50 By Model (Last 30 Days)", + "description": "", + "timeframe": "last30days", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[performance]}}", + "name": "performance", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model" + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "p50_latency", + "shape": "milliseconds" + }, + { + "pattern": ".*" + } + ] + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "p50_latency", + "type": "quantitative", + "title": "Latency p50" + }, + "series": { + "field": "group", + "type": "nominal", + "title": "Model" + } + }, + "style": { + "legendPosition": "bottom", + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Latency p50" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "p50_latency" + ], + "seriesColumn": "group", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Latency p50", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "d596864a-98e3-466c-ba4d-cd59ee6f7f01", + "x": 0, + "y": 16, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Top API Keys By Spend (This Month)", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[apiKeys]}}", + "name": "apiKeys", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "usage_monthly", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "limitStatus", + "displayName": "Limit Status", + "shape": "string", + "visible": false, + "computed": true, + "valueExpression": "{{{{raw}}}}{{ (u => u > 95 ? 'error' : u > 80 ? 'warning' : '')($['limit'] > 0 && $['limit_remaining'] != null ? 100 * ($['limit'] - $['limit_remaining']) / $['limit'] : 0) }}{{{{/raw}}}}" + } + ] + }, + "scope": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}" + }, + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "usage_monthly", + "title": "Spend This Month", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "usage_weekly", + "title": "Spend This Week", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "usage_daily", + "title": "Spend Today", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "usage", + "title": "Total Spend", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "limit", + "title": "Limit", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "limit_remaining", + "title": "Limit Remaining", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "limitUsed", + "title": "Limit Used", + "renderer": { + "type": "progress", + "max": 100 + } + }, + { + "field": "limit_reset", + "title": "Limit Reset", + "renderer": { + "type": "text" + } + }, + { + "field": "disabled", + "title": "Disabled", + "renderer": { + "type": "boolean", + "trueColor": "var(--statusErrorPrimary)", + "falseColor": "var(--textSecondary)" + } + } + ] + }, + "style": { + "richTableRowHighlight": { + "field": "limitStatus", + "colors": { + "warning": "rgba(245,158,11,0.15)", + "error": "rgba(239,68,68,0.15)" + } + } + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "usage_monthly", + "usage_weekly", + "usage_daily", + "usage", + "limit", + "limit_remaining", + "limitUsed", + "limit_reset", + "disabled" + ], + "hiddenColumns": [ + "hash", + "workspace_id", + "created_at", + "expires_at", + "limitStatus" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/provider.dash.json b/plugins/OpenRouter/v1/defaultContent/provider.dash.json new file mode 100644 index 00000000..6980518c --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/provider.dash.json @@ -0,0 +1,624 @@ +{ + "name": "Provider", + "schemaVersion": "1.5", + "timeframe": "last30days", + "variables": [ + "{{variables.[Provider]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "351a6639-f310-42e3-91c2-7beb54aefd69", + "x": 0, + "y": 0, + "w": 1, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Properties", + "description": "", + "timeframe": "none", + "dataStream": { + "id": "datastream-properties", + "name": "properties" + }, + "scope": { + "scope": "{{scopes.[Providers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Provider]}}" + }, + "variables": [ + "{{variables.[Provider]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "headquarters", + "title": "Headquarters", + "renderer": { + "type": "text" + } + }, + { + "field": "datacenters", + "title": "Datacenters", + "renderer": { + "type": "tag-list", + "separator": ", " + } + }, + { + "field": "status_page_url", + "title": "Status Page", + "renderer": { + "type": "link" + } + } + ] + }, + "style": { + "richTableTranspose": true + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true, + "columnOrder": [ + "name", + "headquarters", + "datacenters", + "status_page_url" + ], + "hiddenColumns": [ + "id", + "links", + "type", + "label", + "sourceId", + "sourceType", + "sourceName", + "rawId" + ] + } + } + } + } + }, + { + "i": "39e8dd4a-e54f-4e45-bd83-b0138ca98c1a", + "x": 1, + "y": 0, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Spend (Last 30 Days)", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Providers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Provider]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Provider]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "19df04e1-287e-4e3b-a37c-a89fafc1cd76", + "x": 1, + "y": 2, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Requests (Last 30 Days)", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Providers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Provider]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "request_count", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Provider]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "request_count", + "type": "quantitative", + "title": "Requests" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Requests", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "request_count" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Requests", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "35d28afb-e7eb-4170-8a40-b5e6e2f2b34d", + "x": 0, + "y": 4, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Latency (Last 30 Days)", + "description": "Line: your median (p50) latency each day. Shaded band: p50 to p90, so 9 in 10 requests were faster than its top edge.", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[performance]}}", + "name": "performance", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Providers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Provider]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "p50_latency", + "shape": "milliseconds" + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Provider]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "p50_latency", + "type": "quantitative", + "title": "p50" + }, + "low": { + "field": "p50_latency", + "type": "quantitative", + "title": "p50" + }, + "high": { + "field": "p90_latency", + "type": "quantitative", + "title": "p90" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Latency" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "p50_latency", + "p90_latency" + ], + "seriesColumn": "none", + "showLegend": true, + "legendPosition": "bottom", + "yAxisLabel": "Latency", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "26bc4fa7-e072-4441-ada9-90dab73e0946", + "x": 2, + "y": 4, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Your Throughput p50 (Last 30 Days)", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[performance]}}", + "name": "performance", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Providers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Provider]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "p50_throughput", + "shape": [ + "number", + { + "decimalPlaces": 1 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Provider]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "p50_throughput", + "type": "quantitative", + "title": "Tokens/s" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Tokens/s" + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "p50_throughput" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Tokens/s", + "showYAxisLabel": true, + "showTrendLine": false + } + } + }, + "timeframe": "last30days" + } + }, + { + "i": "2c909c6a-a40e-4f6f-9ac9-2487d77f470a", + "x": 0, + "y": 7, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Model On This Provider (Last 30 Days)", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model", + "filterObjects": { + "scope": "{{scopes.[Providers]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Provider]}}" + } + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Provider]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "Model" + }, + "y": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "group_uniqueValues", + "yAxisData": [ + "total_usage_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "Model", + "yAxisLabel": "Spend ($)", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + }, + "timeframe": "last30days" + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/defaultContent/scopes.json b/plugins/OpenRouter/v1/defaultContent/scopes.json new file mode 100644 index 00000000..0d185f38 --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/scopes.json @@ -0,0 +1,87 @@ +[ + { + "name": "Models", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model" + ] + } + }, + "variable": { + "name": "Model", + "type": "object", + "default": "none", + "allowMultipleSelection": false + } + }, + { + "name": "Model Comparison", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Model" + ] + } + }, + "variable": { + "name": "Compared Models", + "type": "object", + "default": "none", + "allowMultipleSelection": true + } + }, + { + "name": "Providers", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Provider" + ] + } + }, + "variable": { + "name": "Provider", + "type": "object", + "default": "none", + "allowMultipleSelection": false + } + }, + { + "name": "Workspaces", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "Workspace" + ] + } + }, + "variable": { + "name": "Workspace", + "type": "object", + "default": "none", + "allowMultipleSelection": false + } + }, + { + "name": "API Keys", + "matches": { + "sourceType": { + "type": "oneOf", + "values": [ + "API Key" + ] + } + }, + "variable": { + "name": "API Key", + "type": "object", + "default": "none", + "allowMultipleSelection": false + } + } +] diff --git a/plugins/OpenRouter/v1/defaultContent/workspace.dash.json b/plugins/OpenRouter/v1/defaultContent/workspace.dash.json new file mode 100644 index 00000000..77b83fb6 --- /dev/null +++ b/plugins/OpenRouter/v1/defaultContent/workspace.dash.json @@ -0,0 +1,780 @@ +{ + "name": "Workspace", + "schemaVersion": "1.5", + "timeframe": "last30days", + "variables": [ + "{{variables.[Workspace]}}" + ], + "dashboard": { + "_type": "layout/grid", + "columns": 4, + "version": 1, + "contents": [ + { + "i": "ff915e58-be26-44f9-ac25-6ad57c347e6e", + "x": 0, + "y": 0, + "w": 1, + "h": 4, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Settings", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[workspaces]}}", + "name": "workspaces", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "workspaces": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Workspace]}}" + } + } + }, + "variables": [ + "{{variables.[Workspace]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "description", + "title": "Description", + "renderer": { + "type": "text" + } + }, + { + "field": "default_text_model", + "title": "Text Model", + "renderer": { + "type": "text" + } + }, + { + "field": "default_image_model", + "title": "Image Model", + "renderer": { + "type": "text" + } + }, + { + "field": "default_provider_sort", + "title": "Provider Sort", + "renderer": { + "type": "text" + } + }, + { + "field": "disabled_server_tools", + "title": "Disabled Tools", + "renderer": { + "type": "tag-list", + "separator": ", " + } + }, + { + "field": "include_byok_in_budgets", + "title": "BYOK In Budgets", + "renderer": { + "type": "boolean", + "falseColor": "var(--textSecondary)" + } + }, + { + "field": "is_observability_io_logging_enabled", + "title": "Private Logging", + "renderer": { + "type": "boolean", + "falseColor": "var(--textSecondary)" + } + }, + { + "field": "io_logging_sampling_rate", + "title": "Log Sample Rate", + "renderer": { + "type": "text" + } + }, + { + "field": "is_observability_broadcast_enabled", + "title": "Broadcast", + "renderer": { + "type": "boolean", + "falseColor": "var(--textSecondary)" + } + }, + { + "field": "is_data_discount_logging_enabled", + "title": "Discount Logging", + "renderer": { + "type": "boolean", + "falseColor": "var(--textSecondary)" + } + }, + { + "field": "created_at", + "title": "Created", + "renderer": { + "type": "date" + } + } + ] + }, + "style": { + "richTableTranspose": true, + "richTableFontSize": 12 + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": true, + "columnOrder": [ + "name", + "slug", + "description", + "default_text_model", + "default_image_model", + "default_provider_sort", + "disabled_server_tools", + "include_byok_in_budgets", + "is_observability_io_logging_enabled", + "io_logging_sampling_rate", + "is_observability_broadcast_enabled", + "is_data_discount_logging_enabled", + "created_at", + "updated_at" + ], + "hiddenColumns": [ + "id" + ] + } + } + } + } + }, + { + "i": "4b027f1f-ba96-4972-af3f-5b397fb9496f", + "x": 1, + "y": 0, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Workspace]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "total_usage", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Workspace]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "total_usage", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Spend ($)", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "total_usage" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Spend ($)", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "2ef51ad6-de4b-4059-a907-ea2f57b88309", + "x": 1, + "y": 2, + "w": 3, + "h": 2, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Requests Over Time", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "filterObjects": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Workspace]}}" + } + }, + "sort": { + "by": [ + [ + "date", + "asc" + ] + ] + }, + "metadata": [ + { + "name": "request_count", + "shape": [ + "number", + { + "decimalPlaces": 0, + "thousandsSeparator": true + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Workspace]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "line", + "encoding": { + "x": { + "field": "date", + "type": "temporal", + "title": "Date" + }, + "y": { + "field": "request_count", + "type": "quantitative", + "title": "Requests" + } + }, + "style": { + "cartesianShowYAxisTitle": true, + "cartesianYAxisTitle": "Requests", + "cartesianAreaGradient": true + } + } + }, + "visualisation": { + "type": "data-stream-line-graph", + "config": { + "data-stream-line-graph": { + "xAxisColumn": "date", + "yAxisColumn": [ + "request_count" + ], + "seriesColumn": "none", + "showLegend": false, + "legendPosition": "bottom", + "yAxisLabel": "Requests", + "showYAxisLabel": true, + "showTrendLine": false + } + } + } + } + }, + { + "i": "98c1dbfc-ae37-4636-8ea3-8ab5ed8b56e3", + "x": 0, + "y": 4, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By Model", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "model", + "filterObjects": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Workspace]}}" + } + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Workspace]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "bar", + "encoding": { + "x": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "Model" + }, + "y": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "cartesianHorizontal": true, + "cartesianShowXAxisTitle": true, + "cartesianShowYAxisTitle": true + } + } + }, + "visualisation": { + "type": "data-stream-bar-chart", + "config": { + "data-stream-bar-chart": { + "xAxisData": "group_uniqueValues", + "yAxisData": [ + "total_usage_sum" + ], + "xAxisGroup": "none", + "xAxisLabel": "Model", + "yAxisLabel": "Spend ($)", + "showXAxisLabel": true, + "showYAxisLabel": true, + "showLegend": false, + "legendPosition": "bottom", + "showGrid": true, + "horizontalLayout": "horizontal", + "displayMode": "actual", + "showTotals": false, + "showValue": false, + "grouping": false, + "range": { + "type": "auto" + } + } + } + } + } + }, + { + "i": "4d208d06-5051-4bfe-8834-ddef5b530eac", + "x": 2, + "y": 4, + "w": 2, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "Spend By API Key", + "description": "", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[usage]}}", + "name": "usage", + "pluginConfigId": "{{configId}}", + "dataSourceConfig": { + "groupBy": "api_key_id", + "filterObjects": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Workspace]}}" + } + }, + "group": { + "by": [ + [ + "group", + "uniqueValues" + ] + ], + "aggregate": [ + { + "type": "sum", + "names": [ + "total_usage" + ] + } + ] + }, + "sort": { + "by": [ + [ + "total_usage_sum", + "desc" + ] + ], + "top": 10 + }, + "metadata": [ + { + "name": "total_usage_sum", + "shape": [ + "currency", + { + "code": "USD", + "decimalPlaces": 2 + } + ] + }, + { + "pattern": ".*" + } + ] + }, + "variables": [ + "{{variables.[Workspace]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "pie", + "encoding": { + "label": { + "field": "group_uniqueValues", + "type": "nominal", + "title": "API Key" + }, + "value": { + "field": "total_usage_sum", + "type": "quantitative", + "title": "Spend ($)" + } + }, + "style": { + "pieInnerRadius": 55, + "pieDonutCenterValue": "total", + "pieLegendStyle": "table" + } + } + }, + "visualisation": { + "type": "data-stream-donut-chart", + "config": { + "data-stream-donut-chart": { + "valueColumn": "total_usage_sum", + "labelColumn": "group_uniqueValues", + "hideCenterValue": false, + "showValuesAsPercentage": true, + "legendPosition": "auto", + "legendMode": "table" + } + } + } + } + }, + { + "i": "34c93f18-f42c-442f-bd08-2bfba9a897d0", + "x": 0, + "y": 7, + "w": 4, + "h": 3, + "moved": false, + "static": false, + "z": 0, + "config": { + "_type": "tile/data-stream", + "title": "API Keys", + "description": "", + "timeframe": "none", + "activePluginConfigIds": [ + "{{configId}}" + ], + "dataStream": { + "id": "{{dataStreams.[apiKeys]}}", + "name": "apiKeys", + "pluginConfigId": "{{configId}}", + "sort": { + "by": [ + [ + "usage_monthly", + "desc" + ] + ] + }, + "metadata": [ + { + "name": "limitStatus", + "displayName": "Limit Status", + "shape": "string", + "visible": false, + "computed": true, + "valueExpression": "{{{{raw}}}}{{ (u => u > 95 ? 'error' : u > 80 ? 'warning' : '')($['limit'] > 0 && $['limit_remaining'] != null ? 100 * ($['limit'] - $['limit_remaining']) / $['limit'] : 0) }}{{{{/raw}}}}" + } + ] + }, + "scope": { + "scope": "{{scopes.[Workspaces]}}", + "workspace": "{{workspaceId}}", + "variable": "{{variables.[Workspace]}}" + }, + "variables": [ + "{{variables.[Workspace]}}" + ], + "vizSpec": { + "version": "1.0", + "visualization": { + "chartType": "richTable", + "encoding": { + "columns": [ + { + "field": "name", + "title": "Name", + "renderer": { + "type": "text" + } + }, + { + "field": "usage_monthly", + "title": "Spend This Month", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "usage_weekly", + "title": "Spend This Week", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "usage_daily", + "title": "Spend Today", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "usage", + "title": "Total Spend", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "limit", + "title": "Limit", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "limit_remaining", + "title": "Limit Remaining", + "align": "right", + "renderer": { + "type": "text" + } + }, + { + "field": "limitUsed", + "title": "Limit Used", + "renderer": { + "type": "progress", + "max": 100 + } + }, + { + "field": "limit_reset", + "title": "Limit Reset", + "renderer": { + "type": "text" + } + }, + { + "field": "disabled", + "title": "Disabled", + "renderer": { + "type": "boolean", + "trueColor": "var(--statusErrorPrimary)", + "falseColor": "var(--textSecondary)" + } + } + ] + }, + "style": { + "richTableRowHighlight": { + "field": "limitStatus", + "colors": { + "warning": "rgba(245,158,11,0.15)", + "error": "rgba(239,68,68,0.15)" + } + } + } + } + }, + "visualisation": { + "type": "data-stream-table", + "config": { + "data-stream-table": { + "transpose": false, + "columnOrder": [ + "name", + "usage_monthly", + "usage_weekly", + "usage_daily", + "usage", + "limit", + "limit_remaining", + "limitUsed", + "limit_reset", + "disabled" + ], + "hiddenColumns": [ + "hash", + "workspace_id", + "created_at", + "expires_at", + "limitStatus" + ] + } + } + } + } + } + ] + } +} diff --git a/plugins/OpenRouter/v1/docs/README.md b/plugins/OpenRouter/v1/docs/README.md new file mode 100644 index 00000000..398fccac --- /dev/null +++ b/plugins/OpenRouter/v1/docs/README.md @@ -0,0 +1,83 @@ +Monitor your [OpenRouter](https://openrouter.ai) spend, usage, and API keys in SquaredUp via the [OpenRouter API](https://openrouter.ai/docs/api_reference/overview). Compare models by price, benchmarks, and provider performance. + +## Setup + +You will need an OpenRouter **management key** for full access. A standard API key also works, but without workspace, API key, usage, and performance data. + +| Key type | What works | +| -------- | ---------- | +| **Management key** | Everything. | +| **Standard API key** | Models, providers, model providers, benchmarks, rankings, app rankings, session cost, task classifications, and credits. Workspaces, API keys, usage, and performance are unavailable. | + +Management keys can read and manage account, workspace, API key, and usage data, but cannot be used to call models. This plugin only reads data; it never creates, modifies, or deletes anything in OpenRouter. + +1. Sign in to [OpenRouter](https://openrouter.ai). Organization accounts require the **Admin** role to create a management key. +2. Go to [**Settings → Management Keys**](https://openrouter.ai/settings/management-keys) and create a key. See the [management key documentation](https://openrouter.ai/docs/guides/overview/auth/management-api-keys) for details. +3. To use a standard key instead, create one under [**Settings → API Keys**](https://openrouter.ai/settings/keys). A **$0** credit limit works, so the key can read data but never spend credit. +4. Copy the key and paste it into the **API key** field. + +## Configuration fields + +| Field | What it is | Where to find it | Required | +| ----------- | ------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | -------- | +| **API key** | A management key (recommended) or standard API key, sent as a Bearer token. | OpenRouter → **Settings → Management Keys** (or **Settings → API Keys**). | Yes | + +On save, the plugin checks the key in two steps. An invalid, disabled, or expired key fails setup. A valid standard API key passes with a warning that workspaces, API keys, usage, and performance need a management key. + +## What this plugin monitors + +- **Spend and usage** — spend, requests, tokens, latency, and throughput over time, broken down by model, provider, workspace, API key, or app. +- **API keys** — spend today, this week, and this month for each key, against its credit limit, plus an expiry warning. +- **Account credits** — credits purchased, used, and remaining. +- **Models** — pricing, context length, modalities, and Artificial Analysis benchmark scores for every model on OpenRouter. +- **Providers** — every provider serving models on OpenRouter, with headquarters and datacenter locations. +- **Provider performance** — current status, price, uptime, latency, and throughput for each provider serving a model. +- **Benchmarks and rankings** — scores from Artificial Analysis, Design Arena, and OpenRouter's own evals, OpenRouter's public leaderboard of the most used models, what share of OpenRouter traffic goes to each kind of task, what a coding-agent session typically costs, and which public apps use OpenRouter most. + +The out-of-the-box dashboards include an account **Overview**; **Model Leaderboards** and **Ecosystem** dashboards covering models, apps, task types, and providers across all of OpenRouter, which work with a standard API key; a **Model Comparison** dashboard that compares any models you pick side by side on price, benchmarks, providers, session cost, and your own usage (the usage tiles need a management key); and a perspective for each **Model**, **Provider**, **Workspace**, and **API Key** (spend and latency tiles need a management key). The Model perspective includes a current view of each provider's status, price, and throughput, and your spend and cost per 1M tokens on each provider. + +## Data streams + +- **Usage** — spend, BYOK spend, requests, and total, prompt, completion, reasoning, and cached tokens over time, with cost per 1M tokens, optionally grouped by model, provider, workspace, API key, app, user, origin, country, finish reason, or streamed, and optionally filtered to selected models, providers, workspaces, or API keys. Any other OpenRouter analytics dimension can be typed in. Usage is reported by canonical slug, with `:free` and `:batch` variants combined with their base model. Account-wide. Management key only. +- **Performance** — latency and time to first token (p50 and p90) and throughput (p50) over time, with the same grouping and filtering as **Usage**. The last 30 days at most. Account-wide. Management key only. +- **API Keys** — API keys in a workspace with spend and limits. Per workspace. Management key only. +- **Workspaces** — workspaces in the account with their default models, provider sort, disabled server tools, whether BYOK spend counts toward budgets, and logging and broadcast settings, optionally filtered to selected workspaces. Account-wide. Management key only. +- **Credits** — credits purchased, used, and remaining. Account-wide. +- **Models** — every model on OpenRouter with pricing ($ per 1M tokens), context length, modalities, Artificial Analysis index scores, and affordability scores (0 to 100, higher is cheaper), optionally filtered to selected models. Prices score on a log scale from 100 at $0.01 per 1M tokens to 0 at the **Affordability ceiling** parameter ($1,000 by default, minimum $1). Includes a permaslug (canonical slug, plus `:free` for free variants) that matches how OpenRouter's public datasets name models. +- **Providers** — every provider on OpenRouter, with headquarters and datacenter countries (by name), and status, privacy, and terms links. +- **Model Providers** — providers serving a model, with status, price (including cache reads), uptime over the last 5 minutes, 30 minutes, and day, and latency (p50 to p99) and throughput over the last 30 minutes. Per model. +- **Benchmarks** — model benchmark scores from Artificial Analysis, Design Arena, and OpenRouter evals, one row per model and benchmark. +- **Model Rankings** — the most used models across all OpenRouter traffic, by tokens processed per day, week, or month, optionally narrowed to a use case, language type, modality, or context length. Optionally keep only each period's top models and combine the rest into **Other**, as OpenRouter's own rankings chart does. +- **App Rankings** — the top 100 public apps on OpenRouter by tokens, ranked by most tokens or by trending growth, optionally filtered to a category or subcategory (such as CLI agents or roleplay). +- **Session Cost** — median cost of one coding-agent session routed through OpenRouter, by harness (such as Claude Code or Codex), model, and session length (1 turn to 50+ turns), optionally filtered to a harness, session length, or selected models. Refreshed weekly by OpenRouter. +- **Task Classifications** — share of all OpenRouter requests and tokens by task type (such as code generation or summarization) over the last 7 days, grouped into Code, Data, Agent, and General, with each task's most used model. + +## What gets indexed + +| Object type | API source | Represents | +| ------------- | ------------------------------- | ------------------------------------------------------------------------ | +| **Model** | `GET /models` | A model available through OpenRouter, such as `anthropic/claude-sonnet-4.5`. | +| **Provider** | `GET /providers` | A provider serving models through OpenRouter, such as `Groq`. | +| **Workspace** | `GET /workspaces` | A workspace in the account. Management key only. | +| **API Key** | `GET /keys` (per workspace) | An API key in a workspace, including its expiry date. Management key only. | + +Each API Key stores the ID of its Workspace as a property; no graph relationship is created between them. + +With a standard API key, only models and providers are imported; the workspace and API key import steps are skipped with a warning. + +## Known limitations + +- **Benchmarks, rankings, app rankings, task classifications, and session costs refresh at most once a day** — OpenRouter limits these endpoints to 500 requests a day per account, so the plugin caches them for 24 hours. +- **Rankings licence** — rankings, app ranking, task classification, session cost, and benchmark data is published by OpenRouter under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). Each row of these streams has a hidden **Citation** column with the exact attribution OpenRouter requires, and a hidden **As Of** date. The **Model Leaderboards**, **Model Comparison**, **Ecosystem**, and **Model** dashboards credit the data already; show the citation on any dashboard you build from it. +- **Not every model has benchmark scores** — Artificial Analysis scores cover fewer than half of models; the rest show blank. +- **Usage history** can be queried up to a year back. Grouping by **Provider**, **Origin**, **Country**, **Finish reason**, or **Streamed** is limited to 31 days; longer timeframes return an error. +- **Usage timeframes start at 12 hours** — data is bucketed by hour, day, week, or month to suit the range; periods with no activity are left out rather than shown as zero. +- **Cost per 1M tokens is blended** — it's spend divided by all tokens, including cached and reasoning tokens, so it reflects your mix of traffic rather than a provider's list price. +- **Large usage queries may be truncated** — the stream warns when this happens; narrow the timeframe or filter to specific objects. +- **Model rankings start at 7 days** — the data is daily. Use case and language segments are weekly estimates from sampled traffic, so they're shown weekly even when **Day** is selected. +- **Task classifications cover the last 7 days only** — they come from a sample of OpenRouter traffic, so only shares are available, not request or token counts. +- **Provider status is inferred** — OpenRouter doesn't document its endpoint status codes. The plugin shows `0` as healthy, `-1` to `-3` as warning, and anything lower as error, which matches the uptime OpenRouter reports for those endpoints; check **Uptime (5m)** alongside it. +- **Provider performance is a live snapshot** — it covers the last 5 minutes to 1 day, with no history beyond what SquaredUp records. +- **Filtering usage needs imported objects** — pick models, providers, workspaces, or API keys in **Filter to objects (optional)**; grouped results show their names. Filtering by provider is limited to 31 days. +- **Organization members aren't imported.** +- **Read-only** — the plugin never creates, modifies, or deletes anything in OpenRouter. diff --git a/plugins/OpenRouter/v1/icon.svg b/plugins/OpenRouter/v1/icon.svg new file mode 100644 index 00000000..c3bc9f7d --- /dev/null +++ b/plugins/OpenRouter/v1/icon.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/plugins/OpenRouter/v1/indexDefinitions/default.json b/plugins/OpenRouter/v1/indexDefinitions/default.json new file mode 100644 index 00000000..8a1fbc79 --- /dev/null +++ b/plugins/OpenRouter/v1/indexDefinitions/default.json @@ -0,0 +1,70 @@ +{ + "steps": [ + { + "name": "models", + "dataStream": { + "name": "models" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Model" + }, + "properties": ["author", "canonical_slug", "permaslug", "context_length"] + } + }, + { + "name": "providers", + "dataStream": { + "name": "providers" + }, + "timeframe": "none", + "objectMapping": { + "id": "slug", + "name": "name", + "type": { + "value": "Provider" + }, + "properties": ["headquarters", "datacenters", "status_page_url"] + } + }, + { + "name": "workspaces", + "dataStream": { + "name": "workspaces" + }, + "timeframe": "none", + "objectMapping": { + "id": "id", + "name": "name", + "type": { + "value": "Workspace" + }, + "properties": ["slug"] + }, + "optional": true + }, + { + "name": "apiKeys", + "dataStream": { + "name": "apiKeys" + }, + "scope": { + "query": "g.V().has(\"sourceType\", \"Workspace\")" + }, + "timeframe": "none", + "objectMapping": { + "id": "hash", + "name": "name", + "type": { + "value": "API Key" + }, + "properties": ["workspace_id", "disabled", "created_at", "expires_at"] + }, + "optional": true, + "dependsOn": ["workspaces"] + } + ] +} diff --git a/plugins/OpenRouter/v1/metadata.json b/plugins/OpenRouter/v1/metadata.json new file mode 100644 index 00000000..2137586b --- /dev/null +++ b/plugins/OpenRouter/v1/metadata.json @@ -0,0 +1,54 @@ +{ + "name": "openrouter", + "displayName": "OpenRouter", + "version": "1.0.0", + "author": { + "name": "@AnEvilPenguin", + "type": "community" + }, + "description": "Track OpenRouter spend and usage by workspace, API key, and model, and compare models by price, benchmarks, and provider performance.", + "category": "Monitoring", + "type": "cloud", + "schemaVersion": "2.1", + "importNotSupported": false, + "restrictedToPlatforms": [], + "keywords": [ + "openrouter", + "ai", + "llm", + "models", + "benchmarks", + "cost", + "usage", + "tokens", + "billing" + ], + "objectTypes": ["Model", "Provider", "Workspace", "API Key"], + "links": [ + { + "category": "documentation", + "url": "https://github.com/squaredup/plugins/blob/main/plugins/OpenRouter/v1/docs/README.md", + "label": "Help adding this plugin" + }, + { + "category": "source", + "url": "https://github.com/squaredup/plugins/tree/main/plugins/OpenRouter/v1", + "label": "Repository" + } + ], + "base": { + "plugin": "WebAPI", + "majorVersion": "1", + "config": { + "baseUrl": "https://openrouter.ai/api/v1/", + "authMode": "none", + "headers": [ + { + "key": "Authorization", + "value": "Bearer {{apiKey}}" + } + ], + "queryArgs": [] + } + } +} diff --git a/plugins/OpenRouter/v1/ui.json b/plugins/OpenRouter/v1/ui.json new file mode 100644 index 00000000..ad411ae0 --- /dev/null +++ b/plugins/OpenRouter/v1/ui.json @@ -0,0 +1,12 @@ +[ + { + "type": "password", + "name": "apiKey", + "label": "API key", + "placeholder": "sk-or-v1-...", + "validation": { + "required": true + }, + "help": "Use a [management key](https://openrouter.ai/settings/management-keys) for full access. A standard [API key](https://openrouter.ai/settings/keys) works for everything except workspace, API key, usage, and performance data. This plugin only reads data; it does not create, modify, or delete anything in OpenRouter." + } +]