@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1 → 2.0.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +0 -0
- package/native-manifest.json +1088 -134
- package/package.json +160 -1
- package/plugins/UPSTREAM-LICENSES.md +113 -0
- package/plugins/_provider-icons/LICENSE +21 -0
- package/plugins/_provider-icons/NOTICE +12 -0
- package/plugins/_provider-icons/licenses/CodexBar-MIT.txt +21 -0
- package/plugins/_provider-icons/licenses/LobeHub-MIT.txt +21 -0
- package/plugins/_provider-icons/licenses/UsageStat-Bar-MIT.txt +21 -0
- package/plugins/_provider-icons/manifest.json +1219 -0
- package/plugins/_provider-icons/provenance.json +269 -0
- package/plugins/_provider-icons/source.json +4 -0
- package/plugins/abacus-ai/icon-color.svg +18 -0
- package/plugins/abacus-ai/icon.svg +0 -0
- package/plugins/abacus-ai/plugin.js +0 -0
- package/plugins/abacus-ai/plugin.json +0 -0
- package/plugins/aiand/icon.svg +6 -0
- package/plugins/aiand/plugin.js +108 -0
- package/plugins/aiand/plugin.json +22 -0
- package/plugins/aixy/LICENSE +21 -0
- package/plugins/aixy/plugin.js +261 -0
- package/plugins/aixy/plugin.json +24 -0
- package/plugins/alibaba/icon-color.svg +0 -0
- package/plugins/alibaba/icon.svg +0 -0
- package/plugins/alibaba/plugin.js +0 -0
- package/plugins/alibaba/plugin.json +0 -0
- package/plugins/alibaba-token-plan/icon-color.svg +0 -0
- package/plugins/alibaba-token-plan/icon.svg +0 -0
- package/plugins/alibaba-token-plan/plugin.js +0 -0
- package/plugins/alibaba-token-plan/plugin.json +0 -0
- package/plugins/amp/icon-color.svg +0 -0
- package/plugins/amp/icon-conflict.svg +0 -0
- package/plugins/amp/icon.svg +0 -0
- package/plugins/amp/plugin.js +0 -0
- package/plugins/amp/plugin.json +0 -0
- package/plugins/antigravity/icon-color.svg +0 -0
- package/plugins/antigravity/icon-conflict.svg +0 -0
- package/plugins/antigravity/icon.svg +0 -0
- package/plugins/antigravity/plugin.js +136 -46
- package/plugins/antigravity/plugin.json +0 -0
- package/plugins/antigravity-cli/icon-color.svg +1 -0
- package/plugins/antigravity-cli/icon.svg +1 -3
- package/plugins/antigravity-cli/plugin.js +11 -15
- package/plugins/antigravity-cli/plugin.json +0 -0
- package/plugins/antigravity-ide/icon-color.svg +1 -0
- package/plugins/antigravity-ide/icon.svg +1 -3
- package/plugins/antigravity-ide/plugin.js +0 -0
- package/plugins/antigravity-ide/plugin.json +0 -0
- package/plugins/atlascloud/LICENSE +21 -0
- package/plugins/atlascloud/icon-color.svg +1 -0
- package/plugins/atlascloud/icon.svg +1 -0
- package/plugins/atlascloud/plugin.js +49 -0
- package/plugins/atlascloud/plugin.json +23 -0
- package/plugins/augment/icon-color.svg +14 -0
- package/plugins/augment/icon.svg +0 -0
- package/plugins/augment/plugin.js +0 -0
- package/plugins/augment/plugin.json +0 -0
- package/plugins/aws-bedrock/icon-color.svg +0 -0
- package/plugins/aws-bedrock/icon.svg +0 -0
- package/plugins/aws-bedrock/plugin.js +0 -0
- package/plugins/aws-bedrock/plugin.json +0 -0
- package/plugins/azure-openai/icon-color.svg +0 -0
- package/plugins/azure-openai/icon.svg +0 -0
- package/plugins/azure-openai/plugin.js +0 -0
- package/plugins/azure-openai/plugin.json +0 -0
- package/plugins/bifrost/LICENSE +21 -0
- package/plugins/bifrost/plugin.js +361 -0
- package/plugins/bifrost/plugin.json +23 -0
- package/plugins/chutes/icon.svg +0 -0
- package/plugins/chutes/plugin.js +0 -0
- package/plugins/chutes/plugin.json +0 -0
- package/plugins/claude/icon-color.svg +0 -0
- package/plugins/claude/icon.svg +0 -0
- package/plugins/claude/plugin.js +358 -161
- package/plugins/claude/plugin.json +1 -1
- package/plugins/clawrouter/icon.svg +7 -0
- package/plugins/clawrouter/plugin.js +45 -0
- package/plugins/clawrouter/plugin.json +22 -0
- package/plugins/clinepass/icon.svg +4 -0
- package/plugins/clinepass/plugin.js +87 -0
- package/plugins/clinepass/plugin.json +23 -0
- package/plugins/codebuddy/plugin.js +331 -0
- package/plugins/codebuddy/plugin.json +30 -0
- package/plugins/codebuff/icon-color.svg +92 -0
- package/plugins/codebuff/icon.svg +0 -0
- package/plugins/codebuff/plugin.js +0 -0
- package/plugins/codebuff/plugin.json +0 -0
- package/plugins/coderabbit/plugin.js +25 -0
- package/plugins/coderabbit/plugin.json +12 -0
- package/plugins/codex/icon-color.svg +0 -0
- package/plugins/codex/icon.svg +0 -0
- package/plugins/codex/plugin.js +8 -2
- package/plugins/codex/plugin.json +0 -0
- package/plugins/command-code/icon-color.svg +3 -0
- package/plugins/command-code/icon.svg +0 -0
- package/plugins/command-code/plugin.js +14 -3
- package/plugins/command-code/plugin.json +0 -0
- package/plugins/copilot/icon-color.svg +0 -0
- package/plugins/copilot/icon.svg +1 -1
- package/plugins/copilot/plugin.js +61 -9
- package/plugins/copilot/plugin.json +4 -1
- package/plugins/crof/icon-color.svg +3 -0
- package/plugins/crof/icon.svg +0 -0
- package/plugins/crof/plugin.js +0 -0
- package/plugins/crof/plugin.json +0 -0
- package/plugins/crofai/icon-color.svg +3 -0
- package/plugins/crofai/icon.svg +2 -15
- package/plugins/crofai/plugin.js +0 -0
- package/plugins/crofai/plugin.json +0 -0
- package/plugins/cursor/icon-color.svg +1 -0
- package/plugins/cursor/icon-conflict.svg +0 -0
- package/plugins/cursor/icon.svg +0 -0
- package/plugins/cursor/plugin.js +46 -9
- package/plugins/cursor/plugin.json +3 -2
- package/plugins/cursor-nightly/icon.png +0 -0
- package/plugins/cursor-nightly/plugin.js +45 -8
- package/plugins/cursor-nightly/plugin.json +3 -2
- package/plugins/deepgram/icon.svg +0 -0
- package/plugins/deepgram/plugin.js +0 -0
- package/plugins/deepgram/plugin.json +0 -0
- package/plugins/deepinfra/icon-color.svg +1 -0
- package/plugins/deepinfra/icon.svg +1 -0
- package/plugins/deepinfra/plugin.js +97 -0
- package/plugins/deepinfra/plugin.json +28 -0
- package/plugins/deepseek/icon-color.svg +0 -0
- package/plugins/deepseek/icon.svg +0 -0
- package/plugins/deepseek/plugin.js +150 -59
- package/plugins/deepseek/plugin.json +3 -1
- package/plugins/devin/icon.svg +0 -0
- package/plugins/devin/plugin.js +114 -0
- package/plugins/devin/plugin.json +2 -1
- package/plugins/devpass/LICENSE +21 -0
- package/plugins/devpass/plugin.js +115 -0
- package/plugins/devpass/plugin.json +23 -0
- package/plugins/doubao/icon-color.svg +0 -0
- package/plugins/doubao/icon.svg +0 -0
- package/plugins/doubao/plugin.js +0 -0
- package/plugins/doubao/plugin.json +0 -0
- package/plugins/droid/icon.svg +0 -0
- package/plugins/droid/plugin.json +2 -1
- package/plugins/elevenlabs/icon-color.svg +4 -0
- package/plugins/elevenlabs/icon.svg +0 -0
- package/plugins/elevenlabs/plugin.js +17 -2
- package/plugins/elevenlabs/plugin.json +0 -0
- package/plugins/factory/icon-color.svg +1 -0
- package/plugins/factory/icon-conflict.svg +0 -0
- package/plugins/factory/icon.svg +0 -0
- package/plugins/factory/plugin.js +38 -14
- package/plugins/factory/plugin.json +2 -1
- package/plugins/fireworks-ai/icon-color.svg +1 -0
- package/plugins/fireworks-ai/icon.svg +1 -6
- package/plugins/fireworks-ai/plugin.js +0 -0
- package/plugins/fireworks-ai/plugin.json +0 -0
- package/plugins/gemini/icon-color.svg +0 -0
- package/plugins/gemini/icon.svg +0 -0
- package/plugins/gemini/plugin.js +0 -0
- package/plugins/gemini/plugin.json +0 -0
- package/plugins/gemini-apps/LICENSE +22 -0
- package/plugins/gemini-apps/icon-color.svg +1 -0
- package/plugins/gemini-apps/icon.svg +1 -0
- package/plugins/gemini-apps/plugin.js +470 -0
- package/plugins/gemini-apps/plugin.json +19 -0
- package/plugins/gitkraken/LICENSE +21 -0
- package/plugins/gitkraken/plugin.js +153 -0
- package/plugins/gitkraken/plugin.json +24 -0
- package/plugins/grok/icon-color.svg +1 -0
- package/plugins/grok/icon.svg +0 -0
- package/plugins/grok/plugin.js +30 -5
- package/plugins/grok/plugin.json +3 -1
- package/plugins/groqcloud/icon-color.svg +1 -0
- package/plugins/groqcloud/icon.svg +0 -0
- package/plugins/groqcloud/plugin.js +0 -0
- package/plugins/groqcloud/plugin.json +0 -0
- package/plugins/helmcode/LICENSE +21 -0
- package/plugins/helmcode/plugin.js +188 -0
- package/plugins/helmcode/plugin.json +24 -0
- package/plugins/huggingface/LICENSE +21 -0
- package/plugins/huggingface/icon-color.svg +1 -0
- package/plugins/huggingface/icon.svg +1 -0
- package/plugins/huggingface/plugin.js +293 -0
- package/plugins/huggingface/plugin.json +25 -0
- package/plugins/hyper/LICENSE +21 -0
- package/plugins/hyper/plugin.js +131 -0
- package/plugins/hyper/plugin.json +26 -0
- package/plugins/ibmbob/icon.svg +23 -0
- package/plugins/ibmbob/plugin.js +61 -0
- package/plugins/ibmbob/plugin.json +22 -0
- package/plugins/jetbrains-ai-assistant/icon-color.svg +0 -0
- package/plugins/jetbrains-ai-assistant/icon-conflict.svg +0 -0
- package/plugins/jetbrains-ai-assistant/icon.svg +0 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +0 -0
- package/plugins/jetbrains-ai-assistant/plugin.json +0 -0
- package/plugins/kilo/icon-color.svg +1 -0
- package/plugins/kilo/icon.svg +0 -0
- package/plugins/kilo/plugin.js +0 -0
- package/plugins/kilo/plugin.json +0 -0
- package/plugins/kimi/icon-color.svg +0 -0
- package/plugins/kimi/icon-conflict.svg +0 -0
- package/plugins/kimi/icon.svg +0 -0
- package/plugins/kimi/plugin.js +122 -141
- package/plugins/kimi/plugin.json +5 -2
- package/plugins/kimi-k2/icon-color.svg +0 -0
- package/plugins/kimi-k2/icon.svg +0 -0
- package/plugins/kimi-k2/plugin.js +0 -0
- package/plugins/kimi-k2/plugin.json +0 -0
- package/plugins/kiro/icon-color.svg +0 -0
- package/plugins/kiro/icon-conflict.svg +0 -0
- package/plugins/kiro/icon.svg +0 -0
- package/plugins/kiro/plugin.js +49 -10
- package/plugins/kiro/plugin.json +3 -1
- package/plugins/litellm/icon.svg +0 -0
- package/plugins/litellm/plugin.js +54 -3
- package/plugins/litellm/plugin.json +0 -0
- package/plugins/llm-proxy/icon.svg +0 -0
- package/plugins/llm-proxy/plugin.js +0 -0
- package/plugins/llm-proxy/plugin.json +0 -0
- package/plugins/llmman/LICENSE +21 -0
- package/plugins/llmman/plugin.js +133 -0
- package/plugins/llmman/plugin.json +23 -0
- package/plugins/longcat/icon-color.svg +1 -0
- package/plugins/longcat/icon.svg +1 -0
- package/plugins/longcat/plugin.js +182 -0
- package/plugins/longcat/plugin.json +23 -0
- package/plugins/manus/icon-color.svg +6 -0
- package/plugins/manus/icon.svg +0 -0
- package/plugins/manus/plugin.js +0 -0
- package/plugins/manus/plugin.json +0 -0
- package/plugins/mimo/icon-color.svg +4 -0
- package/plugins/mimo/icon.svg +4 -1
- package/plugins/mimo/plugin.js +0 -0
- package/plugins/mimo/plugin.json +0 -0
- package/plugins/minimax/icon-color.svg +0 -0
- package/plugins/minimax/icon-conflict.svg +0 -0
- package/plugins/minimax/icon.svg +0 -0
- package/plugins/minimax/plugin.js +25 -31
- package/plugins/minimax/plugin.json +0 -0
- package/plugins/mistral/icon-color.svg +0 -0
- package/plugins/mistral/icon.svg +0 -0
- package/plugins/mistral/plugin.js +110 -5
- package/plugins/mistral/plugin.json +0 -0
- package/plugins/moonshot/icon-color.svg +1 -0
- package/plugins/moonshot/icon.svg +0 -0
- package/plugins/moonshot/plugin.js +8 -6
- package/plugins/moonshot/plugin.json +0 -0
- package/plugins/muse/LICENSE +21 -0
- package/plugins/muse/plugin.js +319 -0
- package/plugins/muse/plugin.json +26 -0
- package/plugins/nanogpt/icon-color.svg +0 -0
- package/plugins/nanogpt/icon.svg +0 -0
- package/plugins/nanogpt/plugin.js +0 -0
- package/plugins/nanogpt/plugin.json +0 -0
- package/plugins/neuralwatt/icon.svg +0 -0
- package/plugins/neuralwatt/plugin.js +0 -0
- package/plugins/neuralwatt/plugin.json +0 -0
- package/plugins/notion/icon.svg +1 -0
- package/plugins/notion/plugin.js +282 -0
- package/plugins/notion/plugin.json +29 -0
- package/plugins/nous/LICENSE +21 -0
- package/plugins/nous/icon-color.svg +1 -0
- package/plugins/nous/icon.svg +1 -0
- package/plugins/nous/plugin.js +124 -0
- package/plugins/nous/plugin.json +24 -0
- package/plugins/ollama/icon-color.svg +1 -0
- package/plugins/ollama/icon.svg +0 -0
- package/plugins/ollama/plugin.js +257 -56
- package/plugins/ollama/plugin.json +6 -3
- package/plugins/openai-api/icon-color.svg +1 -0
- package/plugins/openai-api/icon.svg +0 -0
- package/plugins/openai-api/plugin.js +0 -0
- package/plugins/openai-api/plugin.json +0 -0
- package/plugins/opencode/icon-color.svg +1 -0
- package/plugins/opencode/icon.svg +0 -0
- package/plugins/opencode/plugin.js +0 -0
- package/plugins/opencode/plugin.json +0 -0
- package/plugins/opencode-go/icon-color.svg +1 -0
- package/plugins/opencode-go/icon-conflict.svg +0 -0
- package/plugins/opencode-go/icon.svg +0 -0
- package/plugins/opencode-go/plugin.js +103 -17
- package/plugins/opencode-go/plugin.json +5 -2
- package/plugins/openrouter/icon-color.svg +1 -0
- package/plugins/openrouter/icon.svg +0 -0
- package/plugins/openrouter/plugin.js +371 -114
- package/plugins/openrouter/plugin.json +6 -0
- package/plugins/perplexity/icon-color.svg +0 -0
- package/plugins/perplexity/icon-conflict.svg +0 -0
- package/plugins/perplexity/icon.svg +0 -0
- package/plugins/perplexity/plugin.js +0 -0
- package/plugins/perplexity/plugin.json +0 -0
- package/plugins/pi/plugin.js +113 -0
- package/plugins/pi/plugin.json +11 -0
- package/plugins/poe/icon.svg +0 -0
- package/plugins/poe/plugin.js +24 -18
- package/plugins/poe/plugin.json +2 -0
- package/plugins/qoder/icon.svg +3 -0
- package/plugins/qoder/plugin.js +227 -0
- package/plugins/qoder/plugin.json +23 -0
- package/plugins/qwencloud/icon-color.svg +1 -0
- package/plugins/qwencloud/icon.svg +1 -0
- package/plugins/qwencloud/plugin.js +677 -0
- package/plugins/qwencloud/plugin.json +29 -0
- package/plugins/raycast/LICENSE +21 -0
- package/plugins/raycast/plugin.js +174 -0
- package/plugins/raycast/plugin.json +24 -0
- package/plugins/replicate/LICENSE +21 -0
- package/plugins/replicate/icon-color.svg +1 -0
- package/plugins/replicate/icon.svg +1 -0
- package/plugins/replicate/plugin.js +165 -0
- package/plugins/replicate/plugin.json +24 -0
- package/plugins/sakana/icon.svg +5 -0
- package/plugins/sakana/plugin.js +156 -0
- package/plugins/sakana/plugin.json +23 -0
- package/plugins/stepfun/icon-color.svg +0 -0
- package/plugins/stepfun/icon.svg +0 -0
- package/plugins/stepfun/plugin.js +0 -0
- package/plugins/stepfun/plugin.json +0 -0
- package/plugins/sub2api/icon.svg +4 -0
- package/plugins/sub2api/plugin.js +191 -0
- package/plugins/sub2api/plugin.json +16 -0
- package/plugins/synthetic/icon-color.svg +14 -0
- package/plugins/synthetic/icon-conflict.svg +0 -0
- package/plugins/synthetic/icon.svg +0 -0
- package/plugins/synthetic/plugin.js +0 -0
- package/plugins/synthetic/plugin.json +0 -0
- package/plugins/t3chat/icon-color.svg +0 -0
- package/plugins/t3chat/icon.svg +0 -0
- package/plugins/t3chat/plugin.js +0 -0
- package/plugins/t3chat/plugin.json +0 -0
- package/plugins/typesafe/LICENSE +21 -0
- package/plugins/typesafe/plugin.js +225 -0
- package/plugins/typesafe/plugin.json +24 -0
- package/plugins/v0/LICENSE +21 -0
- package/plugins/v0/icon-color.svg +1 -0
- package/plugins/v0/icon.svg +1 -0
- package/plugins/v0/plugin.js +214 -0
- package/plugins/v0/plugin.json +24 -0
- package/plugins/venice/icon-color.svg +0 -0
- package/plugins/venice/icon.svg +0 -0
- package/plugins/venice/plugin.js +50 -1
- package/plugins/venice/plugin.json +2 -1
- package/plugins/vercel/LICENSE +21 -0
- package/plugins/vercel/icon-color.svg +1 -0
- package/plugins/vercel/icon.svg +1 -0
- package/plugins/vercel/plugin.js +55 -0
- package/plugins/vercel/plugin.json +23 -0
- package/plugins/vertex-ai/icon-color.svg +0 -0
- package/plugins/vertex-ai/icon.svg +0 -0
- package/plugins/vertex-ai/plugin.js +0 -0
- package/plugins/vertex-ai/plugin.json +0 -0
- package/plugins/warp/icon-color.svg +0 -0
- package/plugins/warp/icon.svg +0 -0
- package/plugins/warp/plugin.js +0 -0
- package/plugins/warp/plugin.json +0 -0
- package/plugins/wayfinder/icon.svg +5 -0
- package/plugins/wayfinder/plugin.js +47 -0
- package/plugins/wayfinder/plugin.json +16 -0
- package/plugins/windsurf/icon-color.svg +1 -0
- package/plugins/windsurf/icon-conflict.svg +0 -0
- package/plugins/windsurf/icon.svg +0 -0
- package/plugins/windsurf/plugin.js +0 -0
- package/plugins/windsurf/plugin.json +0 -0
- package/plugins/xai/icon-color.svg +1 -0
- package/plugins/xai/icon.svg +1 -0
- package/plugins/xai/plugin.js +162 -0
- package/plugins/xai/plugin.json +28 -0
- package/plugins/xkiro/LICENSE +21 -0
- package/plugins/xkiro/plugin.js +99 -0
- package/plugins/xkiro/plugin.json +23 -0
- package/plugins/zai/icon-color.svg +1 -0
- package/plugins/zai/icon-conflict.svg +0 -0
- package/plugins/zai/icon.svg +0 -0
- package/plugins/zai/plugin.js +111 -161
- package/plugins/zai/plugin.json +4 -1
- package/plugins/zed/icon.svg +0 -0
- package/plugins/zed/plugin.js +0 -0
- package/plugins/zed/plugin.json +0 -0
- package/plugins/zenmux/icon-color.svg +1 -0
- package/plugins/zenmux/icon.svg +1 -0
- package/plugins/zenmux/plugin.js +102 -0
- package/plugins/zenmux/plugin.json +23 -0
- package/plugins/zoommate/icon.svg +1 -0
- package/plugins/zoommate/plugin.js +244 -0
- package/plugins/zoommate/plugin.json +29 -0
- package/usagestat +0 -0
- package/usagestatd +0 -0
|
@@ -1,156 +1,413 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
(function () {
|
|
2
|
+
var DEFAULT_BASE = "https://openrouter.ai/api/v1";
|
|
3
|
+
var ACTIVITY_URL = DEFAULT_BASE + "/activity";
|
|
4
|
+
var ACTIVITY_DAYS = 30;
|
|
5
|
+
var MAX_ACTIVITY_ROWS = 20000;
|
|
5
6
|
|
|
6
|
-
|
|
7
|
+
function clean(value) {
|
|
8
|
+
if (typeof value !== "string") return null;
|
|
9
|
+
var v = value.trim();
|
|
10
|
+
if (!v) return null;
|
|
11
|
+
if (
|
|
12
|
+
v.length >= 2 &&
|
|
13
|
+
((v.charAt(0) === '"' && v.charAt(v.length - 1) === '"') ||
|
|
14
|
+
(v.charAt(0) === "'" && v.charAt(v.length - 1) === "'"))
|
|
15
|
+
) {
|
|
16
|
+
v = v.slice(1, -1).trim();
|
|
17
|
+
}
|
|
18
|
+
return v || null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function env(ctx, name) {
|
|
22
|
+
try {
|
|
23
|
+
return clean(ctx.host.env.get(name));
|
|
24
|
+
} catch (_) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function setting(ctx, names) {
|
|
30
|
+
var settings = ctx.provider && ctx.provider.settings ? ctx.provider.settings : {};
|
|
31
|
+
for (var i = 0; i < names.length; i++) {
|
|
32
|
+
var value = clean(settings[names[i]]);
|
|
33
|
+
if (value) return value;
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function readApiKey(ctx) {
|
|
39
|
+
return clean(ctx.provider && ctx.provider.apiKey) || env(ctx, "OPENROUTER_API_KEY");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function readManagementKey(ctx) {
|
|
43
|
+
return setting(ctx, ["managementApiKey", "managementKey", "activityApiKey"]) ||
|
|
44
|
+
env(ctx, "OPENROUTER_MANAGEMENT_API_KEY");
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function readApiBase(ctx) {
|
|
48
|
+
var value = env(ctx, "OPENROUTER_API_BASE") || setting(ctx, ["apiBase", "baseUrl", "apiUrl"]);
|
|
49
|
+
var base = (value || DEFAULT_BASE).replace(/\/+$/, "");
|
|
50
|
+
if (/\/auth$/i.test(base)) base = base.slice(0, -5);
|
|
51
|
+
return ctx.host.http.validateBaseUrl(base || DEFAULT_BASE, true);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function requestJson(ctx, request) {
|
|
55
|
+
var resp;
|
|
56
|
+
try {
|
|
57
|
+
resp = ctx.host.http.request(request);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
ctx.host.log.error("HTTP request failed: " + String(error));
|
|
60
|
+
throw "OpenRouter request failed. Check your connection.";
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
var json = null;
|
|
64
|
+
try {
|
|
65
|
+
json = resp.bodyText ? JSON.parse(resp.bodyText) : null;
|
|
66
|
+
} catch (_) {
|
|
67
|
+
throw "OpenRouter response was not valid JSON.";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return { resp: resp, json: json };
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function fetchOpenRouterJson(ctx, url, key, timeoutMs) {
|
|
74
|
+
var result = requestJson(ctx, {
|
|
7
75
|
method: "GET",
|
|
8
|
-
url:
|
|
76
|
+
url: url,
|
|
9
77
|
headers: {
|
|
10
|
-
|
|
11
|
-
|
|
78
|
+
Authorization: "Bearer " + key,
|
|
79
|
+
Accept: "application/json",
|
|
12
80
|
},
|
|
13
|
-
timeoutMs: 15000
|
|
81
|
+
timeoutMs: timeoutMs || 15000,
|
|
14
82
|
});
|
|
15
|
-
|
|
16
|
-
if (credits.resp.status === 401 || credits.resp.status === 403) {
|
|
83
|
+
if (result.resp.status === 401 || result.resp.status === 403) {
|
|
17
84
|
throw "OpenRouter API key is invalid.";
|
|
18
85
|
}
|
|
19
|
-
if (
|
|
20
|
-
throw "OpenRouter
|
|
86
|
+
if (result.resp.status < 200 || result.resp.status >= 300) {
|
|
87
|
+
throw "OpenRouter request failed (HTTP " + result.resp.status + ").";
|
|
88
|
+
}
|
|
89
|
+
return result.json;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function readNumber(value) {
|
|
93
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
94
|
+
if (typeof value === "string" && value.trim()) {
|
|
95
|
+
var parsed = Number(value.trim().replace(/,/g, ""));
|
|
96
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
21
97
|
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
function clamp(value, min, max) {
|
|
102
|
+
return Math.max(min, Math.min(max, value));
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function round1(value) {
|
|
106
|
+
return Math.round(value * 10) / 10;
|
|
107
|
+
}
|
|
22
108
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
109
|
+
function round2(value) {
|
|
110
|
+
return Math.round(value * 100) / 100;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function money(value) {
|
|
114
|
+
return "$" + round2(value || 0).toFixed(2);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function progressLine(label, used, limit, format) {
|
|
118
|
+
return {
|
|
119
|
+
type: "progress",
|
|
120
|
+
label: label,
|
|
121
|
+
used: used,
|
|
122
|
+
limit: limit,
|
|
123
|
+
format: format || { kind: "percent" },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function appendCreditsMetrics(metrics, data) {
|
|
128
|
+
var totalCredits = readNumber(data.total_credits);
|
|
129
|
+
var totalUsage = readNumber(data.total_usage);
|
|
26
130
|
|
|
27
131
|
if (totalCredits === null || totalUsage === null) {
|
|
28
132
|
throw "OpenRouter credits response did not include usage totals.";
|
|
29
133
|
}
|
|
30
134
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
135
|
+
var remaining = Math.max(0, totalCredits - totalUsage);
|
|
136
|
+
var usedPercent = totalCredits > 0 ? clamp((totalUsage / totalCredits) * 100, 0, 100) : 0;
|
|
137
|
+
metrics.push(progressLine("Credits", round2(totalUsage), round2(totalCredits), { kind: "dollars" }));
|
|
138
|
+
metrics.push({ type: "text", label: "Balance", value: money(remaining) });
|
|
139
|
+
metrics.push({
|
|
140
|
+
type: "text",
|
|
141
|
+
label: "Used",
|
|
142
|
+
value: money(totalUsage) + " (" + round1(usedPercent) + "%)",
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
function quotaFallbackUsage(data) {
|
|
147
|
+
var reset = typeof data.limit_reset === "string" ? data.limit_reset.toLowerCase() : "";
|
|
148
|
+
if (reset === "daily") return readNumber(data.usage_daily);
|
|
149
|
+
if (reset === "weekly") return readNumber(data.usage_weekly);
|
|
150
|
+
if (reset === "monthly") return readNumber(data.usage_monthly);
|
|
151
|
+
return readNumber(data.usage);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function appendKeyMetrics(metrics, data) {
|
|
155
|
+
var limit = readNumber(data.limit);
|
|
156
|
+
if (limit !== null && limit > 0) {
|
|
157
|
+
var remaining = readNumber(data.limit_remaining);
|
|
158
|
+
if (remaining === null) remaining = readNumber(data.limitRemaining);
|
|
159
|
+
var used = null;
|
|
160
|
+
if (remaining !== null) {
|
|
161
|
+
used = limit - clamp(remaining, 0, limit);
|
|
162
|
+
} else {
|
|
163
|
+
used = quotaFallbackUsage(data);
|
|
50
164
|
}
|
|
51
|
-
|
|
165
|
+
if (used !== null && used >= 0 && Number.isFinite(used)) {
|
|
166
|
+
metrics.push(progressLine("Key Cap", round2(used), round2(limit), { kind: "dollars" }));
|
|
167
|
+
}
|
|
168
|
+
}
|
|
52
169
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
170
|
+
appendSpendText(metrics, "Daily Spend", data.usage_daily, "today");
|
|
171
|
+
appendSpendText(metrics, "Weekly Spend", data.usage_weekly, "this week");
|
|
172
|
+
appendSpendText(metrics, "Monthly Spend", data.usage_monthly, "this month");
|
|
173
|
+
|
|
174
|
+
var rateLimit = data.rate_limit || data.rateLimit;
|
|
175
|
+
if (rateLimit && rateLimit.requests !== undefined) {
|
|
176
|
+
var interval = typeof rateLimit.interval === "string" ? " / " + rateLimit.interval : "";
|
|
177
|
+
metrics.push({
|
|
178
|
+
type: "text",
|
|
179
|
+
label: "Rate Limit",
|
|
180
|
+
value: String(rateLimit.requests) + " requests" + interval,
|
|
62
181
|
});
|
|
63
|
-
|
|
64
|
-
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function appendSpendText(metrics, label, value, subtitle) {
|
|
186
|
+
var n = readNumber(value);
|
|
187
|
+
if (n === null || n < 0) return;
|
|
188
|
+
metrics.push({ type: "text", label: label, value: money(n), subtitle: subtitle });
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
function parseDay(value) {
|
|
192
|
+
if (typeof value === "string") {
|
|
193
|
+
var trimmed = value.trim();
|
|
194
|
+
var match = trimmed.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
195
|
+
if (match) {
|
|
196
|
+
var calendarMs = Date.parse(match[1] + "T00:00:00Z");
|
|
197
|
+
return Number.isFinite(calendarMs) && new Date(calendarMs).toISOString().slice(0, 10) === match[1] ? match[1] : null;
|
|
65
198
|
}
|
|
66
|
-
|
|
67
|
-
|
|
199
|
+
var ms = Date.parse(trimmed);
|
|
200
|
+
if (Number.isFinite(ms)) return new Date(ms).toISOString().slice(0, 10);
|
|
68
201
|
}
|
|
202
|
+
if (typeof value === "number" && Number.isFinite(value)) {
|
|
203
|
+
var date = new Date(value > 1000000000000 ? value : value * 1000);
|
|
204
|
+
return Number.isFinite(date.getTime()) ? date.toISOString().slice(0, 10) : null;
|
|
205
|
+
}
|
|
206
|
+
return null;
|
|
207
|
+
}
|
|
69
208
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
source: "api",
|
|
73
|
-
metrics
|
|
74
|
-
};
|
|
209
|
+
function dayToMs(day) {
|
|
210
|
+
return Date.parse(day + "T00:00:00Z");
|
|
75
211
|
}
|
|
76
|
-
};
|
|
77
212
|
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
if (typeof value === "string" && value.trim()) {
|
|
81
|
-
return value.trim();
|
|
213
|
+
function shortDay(day) {
|
|
214
|
+
return Number(day.slice(5, 7)) + "/" + Number(day.slice(8, 10));
|
|
82
215
|
}
|
|
83
|
-
throw "No OPENROUTER_API_KEY found.";
|
|
84
|
-
}
|
|
85
216
|
|
|
86
|
-
function
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
217
|
+
function latestCompletedUtcDay(ctx) {
|
|
218
|
+
var nowMs = Date.parse(ctx.nowIso);
|
|
219
|
+
if (!Number.isFinite(nowMs)) nowMs = Date.now();
|
|
220
|
+
var now = new Date(nowMs);
|
|
221
|
+
var today = Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
|
|
222
|
+
return new Date(today - 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
|
|
90
223
|
}
|
|
91
|
-
return "https://openrouter.ai/api/v1/auth";
|
|
92
|
-
}
|
|
93
224
|
|
|
94
|
-
function
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
throw "OpenRouter
|
|
225
|
+
function activityRowCost(row, index) {
|
|
226
|
+
var metered = readNumber(row.usage);
|
|
227
|
+
if (metered === null || metered < 0) throw "OpenRouter Activity usage is invalid at row " + index + ".";
|
|
228
|
+
var estimated = readNumber(row.byok_usage_inference);
|
|
229
|
+
if (estimated === null && row.byok_usage_inference != null) throw "OpenRouter Activity BYOK usage is invalid at row " + index + ".";
|
|
230
|
+
if (estimated === null) estimated = 0;
|
|
231
|
+
if (estimated < 0) throw "OpenRouter Activity BYOK usage is invalid at row " + index + ".";
|
|
232
|
+
var total = metered + estimated;
|
|
233
|
+
if (!Number.isFinite(total)) throw "OpenRouter Activity cost total is invalid.";
|
|
234
|
+
return { metered: metered, estimated: estimated, total: total };
|
|
101
235
|
}
|
|
102
236
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
237
|
+
function tokenCount(value) {
|
|
238
|
+
if (value == null) return 0;
|
|
239
|
+
var n = readNumber(value);
|
|
240
|
+
if (!Number.isSafeInteger(n) || n < 0) throw "OpenRouter Activity token count is invalid.";
|
|
241
|
+
return n;
|
|
108
242
|
}
|
|
109
243
|
|
|
110
|
-
|
|
111
|
-
|
|
244
|
+
function rowId(value) {
|
|
245
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
246
|
+
return clean(value) || "";
|
|
247
|
+
}
|
|
112
248
|
|
|
113
|
-
function
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
249
|
+
function summarizeActivityPayloads(payloads, latestCompleted) {
|
|
250
|
+
var latestMs = dayToMs(latestCompleted);
|
|
251
|
+
var cutoffMs = latestMs - (ACTIVITY_DAYS - 1) * 24 * 60 * 60 * 1000;
|
|
252
|
+
var seen = {};
|
|
253
|
+
var byDay = {};
|
|
254
|
+
var total = 0;
|
|
255
|
+
var estimated = 0;
|
|
256
|
+
var rowsSeen = 0;
|
|
257
|
+
var aggregateTokens = 0;
|
|
258
|
+
var aggregateRequests = 0;
|
|
259
|
+
|
|
260
|
+
for (var p = 0; p < payloads.length; p++) {
|
|
261
|
+
var rows = payloads[p] && Array.isArray(payloads[p].data) ? payloads[p].data : null;
|
|
262
|
+
if (!rows) throw "OpenRouter Activity response missing data array.";
|
|
263
|
+
rowsSeen += rows.length;
|
|
264
|
+
if (rowsSeen > MAX_ACTIVITY_ROWS) throw "OpenRouter Activity returned too many rows.";
|
|
265
|
+
for (var i = 0; i < rows.length; i++) {
|
|
266
|
+
var row = rows[i];
|
|
267
|
+
if (!row || typeof row !== "object") throw "OpenRouter Activity row is invalid.";
|
|
268
|
+
var day = parseDay(row.date);
|
|
269
|
+
if (!day) throw "OpenRouter Activity row is missing a usable date.";
|
|
270
|
+
var dayMs = dayToMs(day);
|
|
271
|
+
if (dayMs < cutoffMs || dayMs > latestMs) continue;
|
|
272
|
+
var model = clean(row.model_permaslug) || clean(row.model) || "";
|
|
273
|
+
if (model.length > 512) throw "OpenRouter Activity model name is too long.";
|
|
274
|
+
var cost = activityRowCost(row, i);
|
|
275
|
+
var input = tokenCount(row.prompt_tokens);
|
|
276
|
+
var output = tokenCount(row.completion_tokens);
|
|
277
|
+
var combined = tokenCount(input + output);
|
|
278
|
+
var reasoning = tokenCount(row.reasoning_tokens);
|
|
279
|
+
if (reasoning > output) throw "OpenRouter Activity reasoning tokens exceed completion tokens.";
|
|
280
|
+
var identity = JSON.stringify([
|
|
281
|
+
day,
|
|
282
|
+
model,
|
|
283
|
+
rowId(row.endpoint_id),
|
|
284
|
+
clean(row.provider_name) || "",
|
|
285
|
+
clean(row.workspace_id) || "",
|
|
286
|
+
]);
|
|
287
|
+
var signature = JSON.stringify([input, output, reasoning, tokenCount(row.requests), cost.metered, cost.estimated]);
|
|
288
|
+
if (seen[identity]) {
|
|
289
|
+
if (seen[identity] !== signature) throw "OpenRouter Activity contains conflicting duplicate rows.";
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
seen[identity] = signature;
|
|
293
|
+
aggregateTokens = tokenCount(aggregateTokens + combined);
|
|
294
|
+
aggregateRequests = tokenCount(aggregateRequests + tokenCount(row.requests));
|
|
295
|
+
total += cost.total;
|
|
296
|
+
estimated += cost.estimated;
|
|
297
|
+
if (!Number.isFinite(total) || !Number.isFinite(estimated)) throw "OpenRouter Activity cost total is invalid.";
|
|
298
|
+
var daily = byDay[day] || { date: day, costUsd: 0, inputTokens: 0, outputTokens: 0, reasoningOutputTokens: 0, totalTokens: 0 };
|
|
299
|
+
daily.costUsd += cost.total;
|
|
300
|
+
daily.inputTokens = tokenCount(daily.inputTokens + input);
|
|
301
|
+
// Reasoning is a subset of completion tokens; the history store sums these fields.
|
|
302
|
+
daily.outputTokens = tokenCount(daily.outputTokens + (output - reasoning));
|
|
303
|
+
daily.reasoningOutputTokens = tokenCount(daily.reasoningOutputTokens + reasoning);
|
|
304
|
+
daily.totalTokens = tokenCount(daily.totalTokens + combined);
|
|
305
|
+
byDay[day] = daily;
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return { total: total, estimated: estimated, byDay: byDay };
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function fetchActivityPayload(ctx, managementKey, date) {
|
|
313
|
+
var url = ACTIVITY_URL;
|
|
314
|
+
if (date) url += "?date=" + encodeURIComponent(date);
|
|
315
|
+
var result = requestJson(ctx, {
|
|
316
|
+
method: "GET",
|
|
317
|
+
url: url,
|
|
318
|
+
headers: {
|
|
319
|
+
Authorization: "Bearer " + managementKey,
|
|
320
|
+
Accept: "application/json",
|
|
321
|
+
},
|
|
322
|
+
timeoutMs: 3000,
|
|
123
323
|
});
|
|
324
|
+
if (result.resp.status === 401 || result.resp.status === 403) {
|
|
325
|
+
throw "OpenRouter management API key is invalid.";
|
|
326
|
+
}
|
|
327
|
+
if (result.resp.status < 200 || result.resp.status >= 300) {
|
|
328
|
+
throw "OpenRouter Activity request failed (HTTP " + result.resp.status + ").";
|
|
329
|
+
}
|
|
330
|
+
return result.json;
|
|
124
331
|
}
|
|
125
332
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
333
|
+
function appendActivityMetrics(ctx, metrics, managementKey) {
|
|
334
|
+
var latestCompleted = latestCompletedUtcDay(ctx);
|
|
335
|
+
var summary = summarizeActivityPayloads([
|
|
336
|
+
fetchActivityPayload(ctx, managementKey, null),
|
|
337
|
+
fetchActivityPayload(ctx, managementKey, latestCompleted),
|
|
338
|
+
], latestCompleted);
|
|
339
|
+
|
|
129
340
|
metrics.push({
|
|
130
341
|
type: "text",
|
|
131
|
-
label: "
|
|
132
|
-
value:
|
|
342
|
+
label: "Cost",
|
|
343
|
+
value: money(summary.total),
|
|
344
|
+
subtitle: "Last 30 completed days (UTC)" + (summary.estimated > 0 ? "; includes " + money(summary.estimated) + " estimated BYOK inference" : ""),
|
|
133
345
|
});
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
346
|
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
347
|
+
var days = Object.keys(summary.byDay).sort();
|
|
348
|
+
var chartPoints = [];
|
|
349
|
+
var dailyRows = [];
|
|
350
|
+
for (var i = 0; i < days.length; i++) {
|
|
351
|
+
var amount = summary.byDay[days[i]].costUsd;
|
|
352
|
+
chartPoints.push({
|
|
353
|
+
label: shortDay(days[i]),
|
|
354
|
+
value: amount,
|
|
355
|
+
valueLabel: money(amount),
|
|
356
|
+
});
|
|
357
|
+
dailyRows.push(summary.byDay[days[i]]);
|
|
358
|
+
}
|
|
359
|
+
if (chartPoints.length) {
|
|
360
|
+
metrics.push({
|
|
361
|
+
type: "barChart",
|
|
362
|
+
label: "Usage Trend",
|
|
363
|
+
points: chartPoints,
|
|
364
|
+
note: "OpenRouter Activity spend from completed UTC days." + (summary.estimated > 0 ? " Includes estimated BYOK inference." : ""),
|
|
365
|
+
color: "#7c3aed",
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
try {
|
|
370
|
+
if (ctx.host.usageDaily && typeof ctx.host.usageDaily.ingest === "function" && dailyRows.length) {
|
|
371
|
+
ctx.host.usageDaily.ingest({
|
|
372
|
+
displayName: "OpenRouter",
|
|
373
|
+
source: summary.estimated > 0 ? "openrouter_activity_estimated" : "openrouter_activity",
|
|
374
|
+
daily: dailyRows,
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
} catch (_) {}
|
|
142
378
|
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
379
|
|
|
146
|
-
function
|
|
147
|
-
|
|
148
|
-
|
|
380
|
+
function probe(ctx) {
|
|
381
|
+
var apiKey = readApiKey(ctx);
|
|
382
|
+
if (!apiKey) throw "No OPENROUTER_API_KEY found.";
|
|
383
|
+
var apiBase = readApiBase(ctx);
|
|
384
|
+
var metrics = [];
|
|
149
385
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
386
|
+
var credits = fetchOpenRouterJson(ctx, apiBase + "/credits", apiKey, 15000);
|
|
387
|
+
appendCreditsMetrics(metrics, credits && credits.data ? credits.data : {});
|
|
388
|
+
|
|
389
|
+
try {
|
|
390
|
+
var key = fetchOpenRouterJson(ctx, apiBase + "/key", apiKey, 1000);
|
|
391
|
+
if (key && key.data) appendKeyMetrics(metrics, key.data);
|
|
392
|
+
} catch (error) {
|
|
393
|
+
ctx.host.log.warn("OpenRouter key details request degraded: " + String(error));
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
var managementKey = readManagementKey(ctx);
|
|
397
|
+
if (managementKey) {
|
|
398
|
+
try {
|
|
399
|
+
appendActivityMetrics(ctx, metrics, managementKey);
|
|
400
|
+
} catch (error) {
|
|
401
|
+
ctx.host.log.warn("OpenRouter Activity degraded: " + String(error));
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
return {
|
|
406
|
+
displayName: "OpenRouter",
|
|
407
|
+
source: "api",
|
|
408
|
+
metrics: metrics,
|
|
409
|
+
};
|
|
410
|
+
}
|
|
153
411
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
}
|
|
412
|
+
globalThis.__usagestat_plugin = { probe: probe };
|
|
413
|
+
})();
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
"id": "openrouter",
|
|
3
3
|
"name": "OpenRouter",
|
|
4
4
|
"entry": "plugin.js",
|
|
5
|
+
"envVars": ["OPENROUTER_API_KEY", "OPENROUTER_API_BASE", "OPENROUTER_MANAGEMENT_API_KEY"],
|
|
6
|
+
"usageDashboardUrl": "https://openrouter.ai/activity",
|
|
7
|
+
"links": [
|
|
8
|
+
{ "label": "Activity", "url": "https://openrouter.ai/activity" },
|
|
9
|
+
{ "label": "Credits", "url": "https://openrouter.ai/settings/credits" }
|
|
10
|
+
],
|
|
5
11
|
"enabledByDefault": false,
|
|
6
12
|
"supportedModes": ["api"],
|
|
7
13
|
"autoMode": "api"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|