@hashimkarim/usagestat-linux-x64-gnu 2.0.0-alpha.1
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 +57744 -0
- package/native-manifest.json +1414 -0
- package/package.json +254 -0
- package/plugins/abacus-ai/icon.svg +18 -0
- package/plugins/abacus-ai/plugin.js +121 -0
- package/plugins/abacus-ai/plugin.json +17 -0
- package/plugins/alibaba/icon-color.svg +1 -0
- package/plugins/alibaba/icon.svg +1 -0
- package/plugins/alibaba/plugin.js +322 -0
- package/plugins/alibaba/plugin.json +20 -0
- package/plugins/alibaba-token-plan/icon-color.svg +1 -0
- package/plugins/alibaba-token-plan/icon.svg +1 -0
- package/plugins/alibaba-token-plan/plugin.js +544 -0
- package/plugins/alibaba-token-plan/plugin.json +19 -0
- package/plugins/amp/icon-color.svg +1 -0
- package/plugins/amp/icon-conflict.svg +6 -0
- package/plugins/amp/icon.svg +1 -0
- package/plugins/amp/plugin.js +175 -0
- package/plugins/amp/plugin.json +16 -0
- package/plugins/antigravity/icon-color.svg +1 -0
- package/plugins/antigravity/icon-conflict.svg +3 -0
- package/plugins/antigravity/icon.svg +1 -0
- package/plugins/antigravity/plugin.js +739 -0
- package/plugins/antigravity/plugin.json +31 -0
- package/plugins/antigravity-cli/icon.svg +3 -0
- package/plugins/antigravity-cli/plugin.js +570 -0
- package/plugins/antigravity-cli/plugin.json +16 -0
- package/plugins/antigravity-ide/icon.svg +3 -0
- package/plugins/antigravity-ide/plugin.js +257 -0
- package/plugins/antigravity-ide/plugin.json +29 -0
- package/plugins/augment/icon.svg +14 -0
- package/plugins/augment/plugin.js +59 -0
- package/plugins/augment/plugin.json +18 -0
- package/plugins/aws-bedrock/icon-color.svg +1 -0
- package/plugins/aws-bedrock/icon.svg +1 -0
- package/plugins/aws-bedrock/plugin.js +206 -0
- package/plugins/aws-bedrock/plugin.json +18 -0
- package/plugins/azure-openai/icon-color.svg +1 -0
- package/plugins/azure-openai/icon.svg +1 -0
- package/plugins/azure-openai/plugin.js +145 -0
- package/plugins/azure-openai/plugin.json +17 -0
- package/plugins/chutes/icon.svg +7 -0
- package/plugins/chutes/plugin.js +236 -0
- package/plugins/chutes/plugin.json +19 -0
- package/plugins/claude/icon-color.svg +1 -0
- package/plugins/claude/icon.svg +1 -0
- package/plugins/claude/plugin.js +1723 -0
- package/plugins/claude/plugin.json +30 -0
- package/plugins/codebuff/icon.svg +92 -0
- package/plugins/codebuff/plugin.js +113 -0
- package/plugins/codebuff/plugin.json +17 -0
- package/plugins/codex/icon-color.svg +5 -0
- package/plugins/codex/icon.svg +1 -0
- package/plugins/codex/plugin.js +1009 -0
- package/plugins/codex/plugin.json +82 -0
- package/plugins/command-code/icon.svg +3 -0
- package/plugins/command-code/plugin.js +184 -0
- package/plugins/command-code/plugin.json +20 -0
- package/plugins/copilot/icon-color.svg +1 -0
- package/plugins/copilot/icon.svg +1 -0
- package/plugins/copilot/plugin.js +684 -0
- package/plugins/copilot/plugin.json +21 -0
- package/plugins/crof/icon.svg +3 -0
- package/plugins/crof/plugin.js +53 -0
- package/plugins/crof/plugin.json +17 -0
- package/plugins/crofai/icon.svg +16 -0
- package/plugins/crofai/plugin.js +81 -0
- package/plugins/crofai/plugin.json +18 -0
- package/plugins/cursor/icon-conflict.svg +3 -0
- package/plugins/cursor/icon.svg +1 -0
- package/plugins/cursor/plugin.js +1379 -0
- package/plugins/cursor/plugin.json +23 -0
- package/plugins/cursor-nightly/icon.png +0 -0
- package/plugins/cursor-nightly/plugin.js +1379 -0
- package/plugins/cursor-nightly/plugin.json +23 -0
- package/plugins/deepgram/icon.svg +1 -0
- package/plugins/deepgram/plugin.js +20 -0
- package/plugins/deepgram/plugin.json +17 -0
- package/plugins/deepseek/icon-color.svg +1 -0
- package/plugins/deepseek/icon.svg +1 -0
- package/plugins/deepseek/plugin.js +71 -0
- package/plugins/deepseek/plugin.json +17 -0
- package/plugins/devin/icon.svg +5 -0
- package/plugins/devin/plugin.js +341 -0
- package/plugins/devin/plugin.json +16 -0
- package/plugins/doubao/icon-color.svg +1 -0
- package/plugins/doubao/icon.svg +1 -0
- package/plugins/doubao/plugin.js +92 -0
- package/plugins/doubao/plugin.json +17 -0
- package/plugins/droid/icon.svg +1 -0
- package/plugins/droid/plugin.json +20 -0
- package/plugins/elevenlabs/icon.svg +4 -0
- package/plugins/elevenlabs/plugin.js +48 -0
- package/plugins/elevenlabs/plugin.json +18 -0
- package/plugins/factory/icon-conflict.svg +1 -0
- package/plugins/factory/icon.svg +1 -0
- package/plugins/factory/plugin.js +487 -0
- package/plugins/factory/plugin.json +15 -0
- package/plugins/fireworks-ai/icon.svg +6 -0
- package/plugins/fireworks-ai/plugin.js +370 -0
- package/plugins/fireworks-ai/plugin.json +19 -0
- package/plugins/gemini/icon-color.svg +1 -0
- package/plugins/gemini/icon.svg +1 -0
- package/plugins/gemini/plugin.js +460 -0
- package/plugins/gemini/plugin.json +16 -0
- package/plugins/grok/icon.svg +1 -0
- package/plugins/grok/plugin.js +297 -0
- package/plugins/grok/plugin.json +19 -0
- package/plugins/groqcloud/icon.svg +1 -0
- package/plugins/groqcloud/plugin.js +117 -0
- package/plugins/groqcloud/plugin.json +19 -0
- package/plugins/jetbrains-ai-assistant/icon-color.svg +14 -0
- package/plugins/jetbrains-ai-assistant/icon-conflict.svg +3 -0
- package/plugins/jetbrains-ai-assistant/icon.svg +14 -0
- package/plugins/jetbrains-ai-assistant/plugin.js +313 -0
- package/plugins/jetbrains-ai-assistant/plugin.json +16 -0
- package/plugins/kilo/icon.svg +1 -0
- package/plugins/kilo/plugin.js +111 -0
- package/plugins/kilo/plugin.json +19 -0
- package/plugins/kimi/icon-color.svg +1 -0
- package/plugins/kimi/icon-conflict.svg +3 -0
- package/plugins/kimi/icon.svg +1 -0
- package/plugins/kimi/plugin.js +358 -0
- package/plugins/kimi/plugin.json +15 -0
- package/plugins/kimi-k2/icon-color.svg +1 -0
- package/plugins/kimi-k2/icon.svg +1 -0
- package/plugins/kimi-k2/plugin.js +58 -0
- package/plugins/kimi-k2/plugin.json +18 -0
- package/plugins/kiro/icon-color.svg +5 -0
- package/plugins/kiro/icon-conflict.svg +1 -0
- package/plugins/kiro/icon.svg +4 -0
- package/plugins/kiro/plugin.js +390 -0
- package/plugins/kiro/plugin.json +16 -0
- package/plugins/litellm/icon.svg +16 -0
- package/plugins/litellm/plugin.js +199 -0
- package/plugins/litellm/plugin.json +16 -0
- package/plugins/llm-proxy/icon.svg +1 -0
- package/plugins/llm-proxy/plugin.js +40 -0
- package/plugins/llm-proxy/plugin.json +17 -0
- package/plugins/manus/icon.svg +6 -0
- package/plugins/manus/plugin.js +50 -0
- package/plugins/manus/plugin.json +17 -0
- package/plugins/mimo/icon.svg +1 -0
- package/plugins/mimo/plugin.js +177 -0
- package/plugins/mimo/plugin.json +19 -0
- package/plugins/minimax/icon-color.svg +1 -0
- package/plugins/minimax/icon-conflict.svg +4 -0
- package/plugins/minimax/icon.svg +1 -0
- package/plugins/minimax/plugin.js +453 -0
- package/plugins/minimax/plugin.json +14 -0
- package/plugins/mistral/icon-color.svg +1 -0
- package/plugins/mistral/icon.svg +1 -0
- package/plugins/mistral/plugin.js +152 -0
- package/plugins/mistral/plugin.json +18 -0
- package/plugins/moonshot/icon.svg +1 -0
- package/plugins/moonshot/plugin.js +43 -0
- package/plugins/moonshot/plugin.json +16 -0
- package/plugins/nanogpt/icon-color.svg +17 -0
- package/plugins/nanogpt/icon.svg +10 -0
- package/plugins/nanogpt/plugin.js +80 -0
- package/plugins/nanogpt/plugin.json +17 -0
- package/plugins/neuralwatt/icon.svg +3 -0
- package/plugins/neuralwatt/plugin.js +152 -0
- package/plugins/neuralwatt/plugin.json +17 -0
- package/plugins/ollama/icon.svg +1 -0
- package/plugins/ollama/plugin.js +92 -0
- package/plugins/ollama/plugin.json +20 -0
- package/plugins/openai-api/icon.svg +1 -0
- package/plugins/openai-api/plugin.js +533 -0
- package/plugins/openai-api/plugin.json +26 -0
- package/plugins/opencode/icon.svg +1 -0
- package/plugins/opencode/plugin.js +342 -0
- package/plugins/opencode/plugin.json +19 -0
- package/plugins/opencode-go/icon-conflict.svg +1 -0
- package/plugins/opencode-go/icon.svg +1 -0
- package/plugins/opencode-go/plugin.js +617 -0
- package/plugins/opencode-go/plugin.json +50 -0
- package/plugins/openrouter/icon.svg +1 -0
- package/plugins/openrouter/plugin.js +156 -0
- package/plugins/openrouter/plugin.json +8 -0
- package/plugins/perplexity/icon-color.svg +1 -0
- package/plugins/perplexity/icon-conflict.svg +1 -0
- package/plugins/perplexity/icon.svg +1 -0
- package/plugins/perplexity/plugin.js +425 -0
- package/plugins/perplexity/plugin.json +19 -0
- package/plugins/poe/icon.svg +1 -0
- package/plugins/poe/plugin.js +190 -0
- package/plugins/poe/plugin.json +19 -0
- package/plugins/stepfun/icon-color.svg +1 -0
- package/plugins/stepfun/icon.svg +1 -0
- package/plugins/stepfun/plugin.js +155 -0
- package/plugins/stepfun/plugin.json +18 -0
- package/plugins/synthetic/icon-conflict.svg +12 -0
- package/plugins/synthetic/icon.svg +14 -0
- package/plugins/synthetic/plugin.js +331 -0
- package/plugins/synthetic/plugin.json +23 -0
- package/plugins/t3chat/icon-color.svg +28 -0
- package/plugins/t3chat/icon.svg +4 -0
- package/plugins/t3chat/plugin.js +243 -0
- package/plugins/t3chat/plugin.json +20 -0
- package/plugins/venice/icon-color.svg +1 -0
- package/plugins/venice/icon.svg +1 -0
- package/plugins/venice/plugin.js +69 -0
- package/plugins/venice/plugin.json +16 -0
- package/plugins/vertex-ai/icon-color.svg +1 -0
- package/plugins/vertex-ai/icon.svg +1 -0
- package/plugins/vertex-ai/plugin.js +172 -0
- package/plugins/vertex-ai/plugin.json +18 -0
- package/plugins/warp/icon-color.svg +10 -0
- package/plugins/warp/icon.svg +6 -0
- package/plugins/warp/plugin.js +108 -0
- package/plugins/warp/plugin.json +18 -0
- package/plugins/windsurf/icon-conflict.svg +3 -0
- package/plugins/windsurf/icon.svg +1 -0
- package/plugins/windsurf/plugin.js +208 -0
- package/plugins/windsurf/plugin.json +16 -0
- package/plugins/zai/icon-conflict.svg +5 -0
- package/plugins/zai/icon.svg +1 -0
- package/plugins/zai/plugin.js +188 -0
- package/plugins/zai/plugin.json +16 -0
- package/plugins/zed/icon.svg +4 -0
- package/plugins/zed/plugin.js +270 -0
- package/plugins/zed/plugin.json +19 -0
- package/usagestat +0 -0
- package/usagestatd +0 -0
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
var LS_SERVICE = "exa.language_server_pb.LanguageServerService"
|
|
3
|
+
var CC_MODEL_BLACKLIST = {
|
|
4
|
+
"MODEL_CHAT_20706": true,
|
|
5
|
+
"MODEL_CHAT_23310": true,
|
|
6
|
+
"MODEL_GOOGLE_GEMINI_2_5_FLASH": true,
|
|
7
|
+
"MODEL_GOOGLE_GEMINI_2_5_FLASH_THINKING": true,
|
|
8
|
+
"MODEL_GOOGLE_GEMINI_2_5_FLASH_LITE": true,
|
|
9
|
+
"MODEL_GOOGLE_GEMINI_2_5_PRO": true,
|
|
10
|
+
"MODEL_PLACEHOLDER_M19": true,
|
|
11
|
+
"MODEL_PLACEHOLDER_M9": true,
|
|
12
|
+
"MODEL_PLACEHOLDER_M12": true,
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function lsOsProperty(ctx) {
|
|
16
|
+
var p = ctx.app && ctx.app.platform
|
|
17
|
+
if (p === "linux" || p === "windows" || p === "macos") return p
|
|
18
|
+
return "linux"
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
// --- LS discovery ---
|
|
22
|
+
|
|
23
|
+
function discoverLs(ctx) {
|
|
24
|
+
var options = {
|
|
25
|
+
processName: "language_server",
|
|
26
|
+
markers: ["antigravity-ide"],
|
|
27
|
+
csrfFlag: "--csrf_token",
|
|
28
|
+
portFlag: "--extension_server_port",
|
|
29
|
+
}
|
|
30
|
+
var settings = ctx.provider && ctx.provider.settings
|
|
31
|
+
if (settings && settings.ideProcessId != null) {
|
|
32
|
+
var pid = Number(settings.ideProcessId)
|
|
33
|
+
if (!Number.isInteger(pid) || pid <= 0 || pid > 4294967295) throw "Invalid ideProcessId; select a running IDE process."
|
|
34
|
+
options.pid = pid
|
|
35
|
+
}
|
|
36
|
+
if (typeof ctx.host.ls.discoverStatus !== "function") return ctx.host.ls.discover(options)
|
|
37
|
+
var report = ctx.host.ls.discoverStatus(options)
|
|
38
|
+
if (report.status === "ready") return report.result
|
|
39
|
+
if (report.status === "missing") return null
|
|
40
|
+
if (report.status === "ambiguous") throw "Multiple IDE instances match; close unused instances or set provider settings.ideProcessId."
|
|
41
|
+
if (report.status === "unsupported") throw { code: "unsupported", message: "Native IDE discovery is unavailable. On Windows, enable the installed Windows PowerShell/CIM components." }
|
|
42
|
+
throw { code: report.reasonCode === "ide-discovery-timed-out" ? "timed-out" : "failed", message: "IDE process discovery is unavailable or access was denied. Run the backend and IDE under the same signed-in user." }
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function probePort(ctx, scheme, port, csrf) {
|
|
46
|
+
ctx.host.http.request({
|
|
47
|
+
method: "POST",
|
|
48
|
+
url: scheme + "://127.0.0.1:" + port + "/" + LS_SERVICE + "/GetUnleashData",
|
|
49
|
+
headers: {
|
|
50
|
+
"Content-Type": "application/json",
|
|
51
|
+
"Connect-Protocol-Version": "1",
|
|
52
|
+
"x-codeium-csrf-token": csrf,
|
|
53
|
+
},
|
|
54
|
+
bodyText: JSON.stringify({
|
|
55
|
+
context: {
|
|
56
|
+
properties: {
|
|
57
|
+
devMode: "false",
|
|
58
|
+
extensionVersion: "unknown",
|
|
59
|
+
ide: "antigravity-ide",
|
|
60
|
+
ideVersion: "unknown",
|
|
61
|
+
os: lsOsProperty(ctx),
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
timeoutMs: 5000,
|
|
66
|
+
dangerouslyIgnoreTls: scheme === "https",
|
|
67
|
+
})
|
|
68
|
+
// Any HTTP response means this port is alive (even 400 validation errors).
|
|
69
|
+
return true
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function findWorkingPort(ctx, discovery) {
|
|
73
|
+
var ports = discovery.ports || []
|
|
74
|
+
for (var i = 0; i < ports.length; i++) {
|
|
75
|
+
var port = ports[i]
|
|
76
|
+
// Try HTTPS first (LS may use self-signed cert), then HTTP
|
|
77
|
+
try { if (probePort(ctx, "https", port, discovery.csrf)) return { port: port, scheme: "https" } } catch (e) { /* ignore */ }
|
|
78
|
+
try { if (probePort(ctx, "http", port, discovery.csrf)) return { port: port, scheme: "http" } } catch (e) { /* ignore */ }
|
|
79
|
+
ctx.host.log.info("port " + port + " probe failed on both schemes")
|
|
80
|
+
}
|
|
81
|
+
if (discovery.extensionPort) return { port: discovery.extensionPort, scheme: "http" }
|
|
82
|
+
return null
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function callLs(ctx, port, scheme, csrf, method, body) {
|
|
86
|
+
var resp = ctx.host.http.request({
|
|
87
|
+
method: "POST",
|
|
88
|
+
url: scheme + "://127.0.0.1:" + port + "/" + LS_SERVICE + "/" + method,
|
|
89
|
+
headers: {
|
|
90
|
+
"Content-Type": "application/json",
|
|
91
|
+
"Connect-Protocol-Version": "1",
|
|
92
|
+
"x-codeium-csrf-token": csrf,
|
|
93
|
+
},
|
|
94
|
+
bodyText: JSON.stringify(body || {}),
|
|
95
|
+
timeoutMs: 10000,
|
|
96
|
+
dangerouslyIgnoreTls: scheme === "https",
|
|
97
|
+
})
|
|
98
|
+
if (resp.status < 200 || resp.status >= 300) {
|
|
99
|
+
ctx.host.log.warn("callLs " + method + " returned " + resp.status)
|
|
100
|
+
return null
|
|
101
|
+
}
|
|
102
|
+
return ctx.util.tryParseJson(resp.bodyText)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
// --- Line builders ---
|
|
106
|
+
|
|
107
|
+
function normalizeLabel(label) {
|
|
108
|
+
// "Gemini 3 Pro (High)" -> "Gemini 3 Pro"
|
|
109
|
+
return label.replace(/\s*\([^)]*\)\s*$/, "").trim()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function poolLabel(normalizedLabel) {
|
|
113
|
+
var lower = normalizedLabel.toLowerCase()
|
|
114
|
+
if (lower.indexOf("gemini") !== -1 && lower.indexOf("pro") !== -1) return "Gemini Pro"
|
|
115
|
+
if (lower.indexOf("gemini") !== -1 && lower.indexOf("flash") !== -1) return "Gemini Flash"
|
|
116
|
+
// All non-Gemini models (Claude, GPT-OSS, etc.) share a single quota pool
|
|
117
|
+
return "Claude"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function modelSortKey(label) {
|
|
121
|
+
var lower = label.toLowerCase()
|
|
122
|
+
// Gemini Pro variants first, then other Gemini, then Claude Opus, then other Claude, then rest
|
|
123
|
+
if (lower.indexOf("gemini") !== -1 && lower.indexOf("pro") !== -1) return "0a_" + label
|
|
124
|
+
if (lower.indexOf("gemini") !== -1) return "0b_" + label
|
|
125
|
+
if (lower.indexOf("claude") !== -1 && lower.indexOf("opus") !== -1) return "1a_" + label
|
|
126
|
+
if (lower.indexOf("claude") !== -1) return "1b_" + label
|
|
127
|
+
return "2_" + label
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
var QUOTA_PERIOD_MS = 5 * 60 * 60 * 1000 // 5 hours
|
|
131
|
+
|
|
132
|
+
function modelLine(ctx, label, remainingFraction, resetTime) {
|
|
133
|
+
var clamped = Math.max(0, Math.min(1, remainingFraction))
|
|
134
|
+
var used = Math.round((1 - clamped) * 100)
|
|
135
|
+
return ctx.line.progress({
|
|
136
|
+
label: label,
|
|
137
|
+
used: used,
|
|
138
|
+
limit: 100,
|
|
139
|
+
format: { kind: "percent" },
|
|
140
|
+
resetsAt: resetTime || undefined,
|
|
141
|
+
periodDurationMs: QUOTA_PERIOD_MS,
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function buildModelLines(ctx, configs) {
|
|
146
|
+
var deduped = {}
|
|
147
|
+
for (var i = 0; i < configs.length; i++) {
|
|
148
|
+
var c = configs[i]
|
|
149
|
+
var label = (typeof c.label === "string") ? c.label.trim() : ""
|
|
150
|
+
if (!label) continue
|
|
151
|
+
var qi = c.quotaInfo
|
|
152
|
+
var frac = (qi && typeof qi.remainingFraction === "number") ? qi.remainingFraction : 0
|
|
153
|
+
var rtime = (qi && qi.resetTime) || undefined
|
|
154
|
+
var pool = poolLabel(normalizeLabel(label))
|
|
155
|
+
if (!deduped[pool] || frac < deduped[pool].remainingFraction) {
|
|
156
|
+
deduped[pool] = {
|
|
157
|
+
label: pool,
|
|
158
|
+
remainingFraction: frac,
|
|
159
|
+
resetTime: rtime,
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
var models = []
|
|
165
|
+
var keys = Object.keys(deduped)
|
|
166
|
+
for (var i = 0; i < keys.length; i++) {
|
|
167
|
+
var m = deduped[keys[i]]
|
|
168
|
+
m.sortKey = modelSortKey(m.label)
|
|
169
|
+
models.push(m)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
models.sort(function (a, b) {
|
|
173
|
+
return a.sortKey < b.sortKey ? -1 : a.sortKey > b.sortKey ? 1 : 0
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
var lines = []
|
|
177
|
+
for (var i = 0; i < models.length; i++) {
|
|
178
|
+
lines.push(modelLine(ctx, models[i].label, models[i].remainingFraction, models[i].resetTime))
|
|
179
|
+
}
|
|
180
|
+
return lines
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
// --- Probe ---
|
|
184
|
+
|
|
185
|
+
function probe(ctx) {
|
|
186
|
+
var discovery = discoverLs(ctx)
|
|
187
|
+
if (!discovery) throw "Start Antigravity IDE and try again."
|
|
188
|
+
|
|
189
|
+
var found = findWorkingPort(ctx, discovery)
|
|
190
|
+
if (!found) throw "Start Antigravity IDE and try again."
|
|
191
|
+
|
|
192
|
+
ctx.host.log.info("using LS at " + found.scheme + "://127.0.0.1:" + found.port)
|
|
193
|
+
|
|
194
|
+
var metadata = {
|
|
195
|
+
ideName: "antigravity-ide",
|
|
196
|
+
extensionName: "antigravity-ide",
|
|
197
|
+
ideVersion: "unknown",
|
|
198
|
+
locale: "en",
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// Try GetUserStatus first, fall back to GetCommandModelConfigs
|
|
202
|
+
var data = null
|
|
203
|
+
try {
|
|
204
|
+
data = callLs(ctx, found.port, found.scheme, discovery.csrf, "GetUserStatus", { metadata: metadata })
|
|
205
|
+
} catch (e) {
|
|
206
|
+
ctx.host.log.warn("GetUserStatus threw: " + String(e))
|
|
207
|
+
}
|
|
208
|
+
var hasUserStatus = data && data.userStatus
|
|
209
|
+
|
|
210
|
+
if (!hasUserStatus) {
|
|
211
|
+
ctx.host.log.warn("GetUserStatus failed, trying GetCommandModelConfigs")
|
|
212
|
+
data = callLs(ctx, found.port, found.scheme, discovery.csrf, "GetCommandModelConfigs", { metadata: metadata })
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// Parse model configs
|
|
216
|
+
var configs
|
|
217
|
+
if (hasUserStatus) {
|
|
218
|
+
configs = (data.userStatus.cascadeModelConfigData || {}).clientModelConfigs || []
|
|
219
|
+
} else if (data && data.clientModelConfigs) {
|
|
220
|
+
configs = data.clientModelConfigs
|
|
221
|
+
} else {
|
|
222
|
+
throw "Start Antigravity IDE and try again."
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
var filtered = []
|
|
226
|
+
for (var j = 0; j < configs.length; j++) {
|
|
227
|
+
var mid = configs[j].modelOrAlias && configs[j].modelOrAlias.model
|
|
228
|
+
if (mid && CC_MODEL_BLACKLIST[mid]) continue
|
|
229
|
+
filtered.push(configs[j])
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
var lines = buildModelLines(ctx, filtered)
|
|
233
|
+
if (lines.length === 0) throw "Start Antigravity IDE and try again."
|
|
234
|
+
|
|
235
|
+
var plan = null
|
|
236
|
+
if (hasUserStatus) {
|
|
237
|
+
// Prefer userTier.name (Google's own subscription system) over the legacy
|
|
238
|
+
// planInfo.planName field inherited from Windsurf/Codeium, which always
|
|
239
|
+
// returns "Pro" for all paid tiers including Google AI Ultra.
|
|
240
|
+
var ut = data.userStatus.userTier
|
|
241
|
+
var userTierName =
|
|
242
|
+
ut && typeof ut.name === "string" && ut.name.trim() ? ut.name.trim() : null
|
|
243
|
+
if (userTierName) {
|
|
244
|
+
plan = userTierName
|
|
245
|
+
} else {
|
|
246
|
+
var ps = data.userStatus.planStatus || {}
|
|
247
|
+
var pi = ps.planInfo || {}
|
|
248
|
+
plan =
|
|
249
|
+
typeof pi.planName === "string" && pi.planName.trim() ? pi.planName.trim() : null
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
return { plan: plan, lines: lines }
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
globalThis.__openusage_plugin = { id: "antigravity-ide", probe: probe }
|
|
257
|
+
})()
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "antigravity-ide",
|
|
4
|
+
"name": "Antigravity IDE",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"icon": "icon.svg",
|
|
8
|
+
"brandColor": "#000000",
|
|
9
|
+
"supportedModes": ["local"],
|
|
10
|
+
"autoMode": "local",
|
|
11
|
+
"lines": [
|
|
12
|
+
{
|
|
13
|
+
"type": "progress",
|
|
14
|
+
"label": "Gemini Pro",
|
|
15
|
+
"scope": "overview",
|
|
16
|
+
"primaryOrder": 1
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"type": "progress",
|
|
20
|
+
"label": "Gemini Flash",
|
|
21
|
+
"scope": "overview"
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
"type": "progress",
|
|
25
|
+
"label": "Claude",
|
|
26
|
+
"scope": "overview"
|
|
27
|
+
}
|
|
28
|
+
]
|
|
29
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
|
|
2
|
+
<g transform="translate(25 0) scale(8.25)" fill="currentColor" stroke="currentColor">
|
|
3
|
+
<path
|
|
4
|
+
d="M8.64,47.51c-.91,0-1.68-.16-2.3-.47-.62-.31-1.09-.79-1.41-1.41-.32-.63-.48-1.39-.48-2.29v-9.27c0-1.14-.23-1.97-.68-2.49-.46-.52-1.27-.79-2.43-.82-.36,0-.65-.14-.87-.41-.22-.27-.33-.59-.33-.94,0-.38.11-.69.33-.94.22-.25.51-.38.87-.41,1.16-.03,1.97-.3,2.43-.82.46-.52.68-1.34.68-2.45v-9.27c0-1.36.36-2.4,1.08-3.1.72-.71,1.76-1.06,3.12-1.06h11.08c.42,0,.76.12,1.04.37.28.25.42.56.42.94,0,.36-.12.66-.35.92-.23.26-.55.39-.94.39h-10.29c-.58,0-1.03.15-1.33.45-.3.3-.46.76-.46,1.39v9.32c0,.82-.17,1.56-.5,2.22-.33.67-.78,1.19-1.33,1.58-.55.38-1.2.57-1.95.57v-.16c.75,0,1.4.19,1.95.57.55.38,1,.91,1.33,1.58.33.67.5,1.41.5,2.23v9.36c0,.63.15,1.09.46,1.39.3.3.75.45,1.33.45h10.29c.39,0,.7.13.94.39.24.26.35.57.35.92s-.14.66-.42.92c-.28.26-.62.39-1.04.39h-11.08Z" />
|
|
5
|
+
<path
|
|
6
|
+
d="M35.79,47.51c-.42,0-.76-.13-1.04-.39-.28-.26-.42-.57-.42-.92s.12-.66.35-.92c.23-.26.55-.39.94-.39h10.29c.58,0,1.03-.15,1.33-.45.3-.3.46-.76.46-1.39v-9.36c0-.82.17-1.56.5-2.22.33-.67.77-1.19,1.33-1.58.55-.38,1.2-.57,1.95-.57v.16c-.75,0-1.4-.19-1.95-.57-.55-.38-1-.91-1.33-1.58-.33-.67-.5-1.41-.5-2.23v-9.32c0-.63-.15-1.09-.46-1.39-.3-.3-.75-.45-1.33-.45h-10.29c-.39,0-.7-.13-.94-.39-.23-.26-.35-.56-.35-.92,0-.38.14-.69.42-.94.28-.25.62-.37,1.04-.37h11.08c1.36,0,2.39.36,3.11,1.06.72.71,1.08,1.74,1.08,3.1v9.27c0,1.12.23,1.94.68,2.45.46.52,1.27.79,2.43.82.36.03.65.16.87.41.22.25.33.56.33.94,0,.36-.11.67-.33.94-.22.27-.51.41-.87.41-1.16.03-1.97.3-2.43.82-.46.52-.68,1.35-.68,2.49v9.27c0,.9-.16,1.66-.48,2.29-.32.63-.79,1.1-1.41,1.41-.62.31-1.39.47-2.31.47h-11.08Z" />
|
|
7
|
+
<path
|
|
8
|
+
d="M38.64,32.95c2.02,0,3.65-1.61,3.65-3.59s-1.64-3.59-3.65-3.59-3.65,1.61-3.65,3.59,1.64,3.59,3.65,3.59Z" />
|
|
9
|
+
<path
|
|
10
|
+
d="M18.18,32.95c2.02,0,3.65-1.61,3.65-3.59s-1.64-3.59-3.65-3.59-3.65,1.61-3.65,3.59,1.64,3.59,3.65,3.59Z" />
|
|
11
|
+
<path
|
|
12
|
+
d="M26.51.95l-.28,7.34c0,.41-.4.62-1.19.62s-1.18-.21-1.18-.62c-.07-1.83-.13-3.25-.17-4.26-.02-1.03-.05-1.76-.07-2.2-.02-.43-.04-.7-.04-.79v-.14c0-.53.49-.79,1.46-.79s1.46.28,1.46.82ZM32.44.95l-.28,7.34c0,.41-.4.62-1.19.62s-1.19-.21-1.19-.62c-.07-1.83-.13-3.25-.17-4.26-.02-1.03-.05-1.76-.07-2.2-.02-.43-.04-.7-.04-.79v-.14c0-.53.49-.79,1.46-.79s1.46.28,1.46.82Z" />
|
|
13
|
+
</g>
|
|
14
|
+
</svg>
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
var API_URL = "https://api.augmentcode.com/v1/user/usage";
|
|
3
|
+
var AUTH_PATHS = [
|
|
4
|
+
"~/.augment/auth.json",
|
|
5
|
+
"~/.config/Code/User/globalStorage/augment.augment-vscode/auth.json",
|
|
6
|
+
];
|
|
7
|
+
|
|
8
|
+
function loadToken(ctx) {
|
|
9
|
+
for (var i = 0; i < AUTH_PATHS.length; i++) {
|
|
10
|
+
try {
|
|
11
|
+
if (!ctx.host.fs.exists(AUTH_PATHS[i])) continue;
|
|
12
|
+
var json = ctx.util.tryParseJson(ctx.host.fs.readText(AUTH_PATHS[i]));
|
|
13
|
+
if (!json) continue;
|
|
14
|
+
var t = json.access_token || json.accessToken;
|
|
15
|
+
if (typeof t === "string" && t.trim()) return t.trim();
|
|
16
|
+
} catch (e) {
|
|
17
|
+
ctx.host.log.warn("augment: failed to read " + AUTH_PATHS[i] + ": " + e);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function probe(ctx) {
|
|
24
|
+
var token = loadToken(ctx);
|
|
25
|
+
if (!token) {
|
|
26
|
+
throw "Augment auth token not found. Sign in to Augment Code in VS Code.";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var result = ctx.util.requestJson({
|
|
30
|
+
method: "GET",
|
|
31
|
+
url: API_URL,
|
|
32
|
+
headers: { Authorization: "Bearer " + token, Accept: "application/json" },
|
|
33
|
+
timeoutMs: 30000,
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
if (ctx.util.isAuthStatus(result.resp.status) || !result.resp.status || result.resp.status >= 400) {
|
|
37
|
+
throw "Augment auth expired. Re-sign in to Augment Code.";
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
var json = result.json || {};
|
|
41
|
+
var used = (json.used_credits || json.usage || 0);
|
|
42
|
+
var limit = (json.credit_limit || json.limit || 100);
|
|
43
|
+
var usedPct = limit > 0 ? Math.min(100, (used / limit) * 100) : 0;
|
|
44
|
+
|
|
45
|
+
var plan = (json.plan || json.subscription || "Augment");
|
|
46
|
+
var lines = [
|
|
47
|
+
ctx.line.progress({
|
|
48
|
+
label: "Credits",
|
|
49
|
+
used: usedPct,
|
|
50
|
+
limit: 100,
|
|
51
|
+
format: { kind: "percent" },
|
|
52
|
+
}),
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
return { plan: plan, lines: lines };
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
globalThis.__openusage_plugin = { id: "augment", probe: probe };
|
|
59
|
+
})();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "augment",
|
|
4
|
+
"name": "Augment",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"brandColor": "#FF5C00",
|
|
8
|
+
"links": [
|
|
9
|
+
{ "label": "Account", "url": "https://app.augmentcode.com/account" },
|
|
10
|
+
{ "label": "Status", "url": "https://status.augmentcode.com" }
|
|
11
|
+
],
|
|
12
|
+
"usageDashboardUrl": "https://app.augmentcode.com/account",
|
|
13
|
+
"supportedModes": ["oauth", "local"],
|
|
14
|
+
"autoMode": "oauth",
|
|
15
|
+
"lines": [
|
|
16
|
+
{ "type": "progress", "label": "Credits", "scope": "overview", "primaryOrder": 1 }
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Bedrock</title><defs><linearGradient id="lobe-icons-bedrock-_R_0_" x1="80%" x2="20%" y1="20%" y2="80%"><stop offset="0%" stop-color="#6350FB"></stop><stop offset="50%" stop-color="#3D8FFF"></stop><stop offset="100%" stop-color="#9AD8F8"></stop></linearGradient></defs><path d="M13.05 15.513h3.08c.214 0 .389.177.389.394v1.82a1.704 1.704 0 011.296 1.661c0 .943-.755 1.708-1.685 1.708-.931 0-1.686-.765-1.686-1.708 0-.807.554-1.484 1.297-1.662v-1.425h-2.69v4.663a.395.395 0 01-.188.338l-2.69 1.641a.385.385 0 01-.405-.002l-4.926-3.086a.395.395 0 01-.185-.336V16.3L2.196 14.87A.395.395 0 012 14.555L2 14.528V9.406c0-.14.073-.27.192-.34l2.465-1.462V4.448c0-.129.062-.249.165-.322l.021-.014L9.77 1.058a.385.385 0 01.407 0l2.69 1.675a.395.395 0 01.185.336V7.6h3.856V5.683a1.704 1.704 0 01-1.296-1.662c0-.943.755-1.708 1.685-1.708.931 0 1.685.765 1.685 1.708 0 .807-.553 1.484-1.296 1.662v2.311a.391.391 0 01-.389.394h-4.245v1.806h6.624a1.69 1.69 0 011.64-1.313c.93 0 1.685.764 1.685 1.707 0 .943-.754 1.708-1.685 1.708a1.69 1.69 0 01-1.64-1.314H13.05v1.937h4.953l.915 1.18a1.66 1.66 0 01.84-.227c.931 0 1.685.764 1.685 1.707 0 .943-.754 1.708-1.685 1.708-.93 0-1.685-.765-1.685-1.708 0-.346.102-.668.276-.937l-.724-.935H13.05v1.806zM9.973 1.856L7.93 3.122V6.09h-.778V3.604L5.435 4.669v2.945l2.11 1.36L9.712 7.61V5.334h.778V7.83c0 .136-.07.263-.184.335L7.963 9.638v2.081l1.422 1.009-.446.646-1.406-.998-1.53 1.005-.423-.66 1.605-1.055v-1.99L5.038 8.29l-2.26 1.34v1.676l1.972-1.189.398.677-2.37 1.429V14.3l2.166 1.258 2.27-1.368.397.677-2.176 1.311V19.3l1.876 1.175 2.365-1.426.398.678-2.017 1.216 1.918 1.201 2.298-1.403v-5.78l-4.758 2.893-.4-.675 5.158-3.136V3.289L9.972 1.856zM16.13 18.47a.913.913 0 00-.908.92c0 .507.406.918.908.918a.913.913 0 00.907-.919.913.913 0 00-.907-.92zm3.63-3.81a.913.913 0 00-.908.92c0 .508.406.92.907.92a.913.913 0 00.908-.92.913.913 0 00-.908-.92zm1.555-4.99a.913.913 0 00-.908.92c0 .507.407.918.908.918a.913.913 0 00.907-.919.913.913 0 00-.907-.92zM17.296 3.1a.913.913 0 00-.907.92c0 .508.406.92.907.92a.913.913 0 00.908-.92.913.913 0 00-.908-.92z" fill="url(#lobe-icons-bedrock-_R_0_)" fill-rule="nonzero"></path></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Bedrock</title><path d="M13.05 15.513h3.08c.214 0 .389.177.389.394v1.82a1.704 1.704 0 011.296 1.661c0 .943-.755 1.708-1.685 1.708-.931 0-1.686-.765-1.686-1.708 0-.807.554-1.484 1.297-1.662v-1.425h-2.69v4.663a.395.395 0 01-.188.338l-2.69 1.641a.385.385 0 01-.405-.002l-4.926-3.086a.395.395 0 01-.185-.336V16.3L2.196 14.87A.395.395 0 012 14.555L2 14.528V9.406c0-.14.073-.27.192-.34l2.465-1.462V4.448c0-.129.062-.249.165-.322l.021-.014L9.77 1.058a.385.385 0 01.407 0l2.69 1.675a.395.395 0 01.185.336V7.6h3.856V5.683a1.704 1.704 0 01-1.296-1.662c0-.943.755-1.708 1.685-1.708.931 0 1.685.765 1.685 1.708 0 .807-.553 1.484-1.296 1.662v2.311a.391.391 0 01-.389.394h-4.245v1.806h6.624a1.69 1.69 0 011.64-1.313c.93 0 1.685.764 1.685 1.707 0 .943-.754 1.708-1.685 1.708a1.69 1.69 0 01-1.64-1.314H13.05v1.937h4.953l.915 1.18a1.66 1.66 0 01.84-.227c.931 0 1.685.764 1.685 1.707 0 .943-.754 1.708-1.685 1.708-.93 0-1.685-.765-1.685-1.708 0-.346.102-.668.276-.937l-.724-.935H13.05v1.806zM9.973 1.856L7.93 3.122V6.09h-.778V3.604L5.435 4.669v2.945l2.11 1.36L9.712 7.61V5.334h.778V7.83c0 .136-.07.263-.184.335L7.963 9.638v2.081l1.422 1.009-.446.646-1.406-.998-1.53 1.005-.423-.66 1.605-1.055v-1.99L5.038 8.29l-2.26 1.34v1.676l1.972-1.189.398.677-2.37 1.429V14.3l2.166 1.258 2.27-1.368.397.677-2.176 1.311V19.3l1.876 1.175 2.365-1.426.398.678-2.017 1.216 1.918 1.201 2.298-1.403v-5.78l-4.758 2.893-.4-.675 5.158-3.136V3.289L9.972 1.856zM16.13 18.47a.913.913 0 00-.908.92c0 .507.406.918.908.918a.913.913 0 00.907-.919.913.913 0 00-.907-.92zm3.63-3.81a.913.913 0 00-.908.92c0 .508.406.92.907.92a.913.913 0 00.908-.92.913.913 0 00-.908-.92zm1.555-4.99a.913.913 0 00-.908.92c0 .507.407.918.908.918a.913.913 0 00.907-.919.913.913 0 00-.907-.92zM17.296 3.1a.913.913 0 00-.907.92c0 .508.406.92.907.92a.913.913 0 00.908-.92.913.913 0 00-.908-.92z"></path></svg>
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
function env(ctx, name) {
|
|
3
|
+
try {
|
|
4
|
+
var value = ctx.host.env.get(name);
|
|
5
|
+
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
6
|
+
} catch (_) {
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function setting(ctx, names) {
|
|
12
|
+
var settings = ctx.provider && ctx.provider.settings ? ctx.provider.settings : {};
|
|
13
|
+
for (var i = 0; i < names.length; i++) {
|
|
14
|
+
var value = settings[names[i]];
|
|
15
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
16
|
+
if (typeof value === "number" && Number.isFinite(value)) return String(value);
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function numberValue(value) {
|
|
22
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
23
|
+
if (typeof value === "string" && value.trim()) {
|
|
24
|
+
var parsed = Number(value.replace(/[$,]/g, ""));
|
|
25
|
+
if (Number.isFinite(parsed)) return parsed;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function credentials(ctx) {
|
|
31
|
+
var accessKeyID = setting(ctx, ["accessKeyId", "accessKeyID"]) || env(ctx, "AWS_ACCESS_KEY_ID");
|
|
32
|
+
var secretAccessKey = setting(ctx, ["secretAccessKey"]) || env(ctx, "AWS_SECRET_ACCESS_KEY");
|
|
33
|
+
var sessionToken = setting(ctx, ["sessionToken"]) || env(ctx, "AWS_SESSION_TOKEN");
|
|
34
|
+
if (accessKeyID && secretAccessKey) {
|
|
35
|
+
return { accessKeyID: accessKeyID, secretAccessKey: secretAccessKey, sessionToken: sessionToken };
|
|
36
|
+
}
|
|
37
|
+
if (env(ctx, "AWS_PROFILE")) {
|
|
38
|
+
throw "AWS profile auth is not supported yet. Export AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY, or run through an AWS credential wrapper that sets them.";
|
|
39
|
+
}
|
|
40
|
+
throw "AWS credentials not configured. Set AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY.";
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function configuredRegion(ctx) {
|
|
44
|
+
return setting(ctx, ["region"]) || env(ctx, "AWS_REGION") || env(ctx, "AWS_DEFAULT_REGION") || "us-east-1";
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function configuredBudget(ctx) {
|
|
48
|
+
return numberValue(setting(ctx, ["budget", "budgetUsd", "budgetUSD"]) || env(ctx, "USAGESTAT_BEDROCK_BUDGET") || env(ctx, "CODEXBAR_BEDROCK_BUDGET"));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function configuredApiUrl(ctx) {
|
|
52
|
+
var url = setting(ctx, ["apiUrl", "apiURL"]) || env(ctx, "USAGESTAT_BEDROCK_API_URL") || env(ctx, "CODEXBAR_BEDROCK_API_URL");
|
|
53
|
+
return url && url.trim() ? url.trim().replace(/\/+$/, "") : null;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function dateString(date) {
|
|
57
|
+
return date.toISOString().slice(0, 10);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function currentMonthRange() {
|
|
61
|
+
var now = new Date();
|
|
62
|
+
var start = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1));
|
|
63
|
+
var tomorrow = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() + 1));
|
|
64
|
+
return { start: dateString(start), end: dateString(tomorrow) };
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function isDataUnavailable(status, body) {
|
|
68
|
+
if (status !== 400 || !body || typeof body !== "object") return false;
|
|
69
|
+
var nested = body.Error || body.error || {};
|
|
70
|
+
var codes = [body.__type, body.code, body.Code, nested.Code, nested.code];
|
|
71
|
+
for (var i = 0; i < codes.length; i++) {
|
|
72
|
+
if (typeof codes[i] === "string" && codes[i].split("#").pop() === "DataUnavailableException") return true;
|
|
73
|
+
}
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function sanitizeBody(text) {
|
|
78
|
+
var compact = String(text || "").replace(/\s+/g, " ").trim();
|
|
79
|
+
return compact.length > 180 ? compact.slice(0, 180) + "..." : compact;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function callCostExplorerPage(ctx, creds, range, nextPageToken) {
|
|
83
|
+
if (!ctx.host.aws || typeof ctx.host.aws._costExplorerRaw !== "function") {
|
|
84
|
+
throw "AWS Cost Explorer host API is unavailable.";
|
|
85
|
+
}
|
|
86
|
+
var raw = ctx.host.aws._costExplorerRaw(JSON.stringify({
|
|
87
|
+
accessKeyId: creds.accessKeyID,
|
|
88
|
+
secretAccessKey: creds.secretAccessKey,
|
|
89
|
+
sessionToken: creds.sessionToken || null,
|
|
90
|
+
apiUrl: configuredApiUrl(ctx),
|
|
91
|
+
startDate: range.start,
|
|
92
|
+
endDate: range.end,
|
|
93
|
+
granularity: "DAILY",
|
|
94
|
+
nextPageToken: nextPageToken || null,
|
|
95
|
+
}));
|
|
96
|
+
var response = ctx.util.tryParseJson(raw);
|
|
97
|
+
if (!response) throw "AWS Cost Explorer host response was invalid.";
|
|
98
|
+
var body = ctx.util.tryParseJson(response.bodyText || "");
|
|
99
|
+
if (response.status === 200) {
|
|
100
|
+
if (!body) throw "AWS Cost Explorer response was not valid JSON.";
|
|
101
|
+
return body;
|
|
102
|
+
}
|
|
103
|
+
if (isDataUnavailable(response.status, body)) {
|
|
104
|
+
ctx.host.log.info("AWS Cost Explorer data unavailable, treating Bedrock spend as zero.");
|
|
105
|
+
return { ResultsByTime: [] };
|
|
106
|
+
}
|
|
107
|
+
throw "AWS Cost Explorer API returned HTTP " + response.status + ": " + sanitizeBody(response.bodyText);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function callCostExplorer(ctx, creds, range) {
|
|
111
|
+
var pages = [];
|
|
112
|
+
var nextPageToken = null;
|
|
113
|
+
var seen = {};
|
|
114
|
+
do {
|
|
115
|
+
var page = callCostExplorerPage(ctx, creds, range, nextPageToken);
|
|
116
|
+
pages.push(page);
|
|
117
|
+
nextPageToken = typeof page.NextPageToken === "string" && page.NextPageToken.trim() ? page.NextPageToken.trim() : null;
|
|
118
|
+
if (nextPageToken) {
|
|
119
|
+
if (seen[nextPageToken]) throw "AWS Cost Explorer returned a repeated page token.";
|
|
120
|
+
seen[nextPageToken] = true;
|
|
121
|
+
}
|
|
122
|
+
} while (nextPageToken);
|
|
123
|
+
return pages;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function parsePages(pages) {
|
|
127
|
+
var total = 0;
|
|
128
|
+
var byDay = {};
|
|
129
|
+
var services = {};
|
|
130
|
+
for (var p = 0; p < pages.length; p++) {
|
|
131
|
+
var results = Array.isArray(pages[p].ResultsByTime) ? pages[p].ResultsByTime : [];
|
|
132
|
+
for (var r = 0; r < results.length; r++) {
|
|
133
|
+
var date = results[r].TimePeriod && results[r].TimePeriod.Start;
|
|
134
|
+
var groups = Array.isArray(results[r].Groups) ? results[r].Groups : [];
|
|
135
|
+
for (var g = 0; g < groups.length; g++) {
|
|
136
|
+
var keys = Array.isArray(groups[g].Keys) ? groups[g].Keys : [];
|
|
137
|
+
var service = keys.length ? String(keys[0]) : "";
|
|
138
|
+
if (service.toLowerCase().indexOf("bedrock") < 0) continue;
|
|
139
|
+
var metric = groups[g].Metrics && groups[g].Metrics.UnblendedCost;
|
|
140
|
+
var amount = numberValue(metric && metric.Amount);
|
|
141
|
+
if (amount === null || amount <= 0) continue;
|
|
142
|
+
total += amount;
|
|
143
|
+
services[service] = true;
|
|
144
|
+
if (typeof date === "string" && date) byDay[date] = (byDay[date] || 0) + amount;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
var daily = [];
|
|
149
|
+
var days = Object.keys(byDay).sort();
|
|
150
|
+
for (var i = 0; i < days.length; i++) {
|
|
151
|
+
daily.push({ date: days[i], costUsd: byDay[days[i]] });
|
|
152
|
+
}
|
|
153
|
+
return { total: total, daily: daily, services: Object.keys(services).sort() };
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function ingestDaily(ctx, daily) {
|
|
157
|
+
if (!daily.length || !ctx.host.usageDaily || typeof ctx.host.usageDaily.ingest !== "function") return;
|
|
158
|
+
try {
|
|
159
|
+
ctx.host.usageDaily.ingest({ displayName: "AWS Bedrock", source: "billing", daily: daily });
|
|
160
|
+
} catch (e) {
|
|
161
|
+
ctx.host.log.warn("AWS Bedrock daily ingest failed: " + String(e));
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
function usd(value) {
|
|
166
|
+
return "$" + (Number(value) || 0).toFixed(2);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function linesFor(total, budget, services) {
|
|
170
|
+
var lines = [];
|
|
171
|
+
if (budget !== null && budget > 0) {
|
|
172
|
+
lines.push({
|
|
173
|
+
type: "progress",
|
|
174
|
+
label: "Monthly budget",
|
|
175
|
+
used: total,
|
|
176
|
+
limit: budget,
|
|
177
|
+
format: { kind: "dollars" },
|
|
178
|
+
detail: "Month to date",
|
|
179
|
+
});
|
|
180
|
+
} else {
|
|
181
|
+
lines.push({ type: "text", label: "Month spend", value: usd(total) });
|
|
182
|
+
}
|
|
183
|
+
if (services && services.length) {
|
|
184
|
+
lines.push({ type: "text", label: "Services", value: services.slice(0, 3).join(", ") });
|
|
185
|
+
}
|
|
186
|
+
return lines;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
function probe(ctx) {
|
|
190
|
+
var creds = credentials(ctx);
|
|
191
|
+
var region = configuredRegion(ctx);
|
|
192
|
+
var budget = configuredBudget(ctx);
|
|
193
|
+
var range = currentMonthRange();
|
|
194
|
+
var pages = callCostExplorer(ctx, creds, range);
|
|
195
|
+
var parsed = parsePages(pages);
|
|
196
|
+
ingestDaily(ctx, parsed.daily);
|
|
197
|
+
return {
|
|
198
|
+
displayName: "AWS Bedrock",
|
|
199
|
+
source: "api",
|
|
200
|
+
plan: region,
|
|
201
|
+
lines: linesFor(parsed.total, budget, parsed.services),
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
globalThis.__openusage_plugin = { id: "aws-bedrock", probe: probe };
|
|
206
|
+
})();
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"id": "aws-bedrock",
|
|
4
|
+
"name": "AWS Bedrock",
|
|
5
|
+
"version": "0.0.1",
|
|
6
|
+
"entry": "plugin.js",
|
|
7
|
+
"brandColor": "#FF9900",
|
|
8
|
+
"links": [
|
|
9
|
+
{ "label": "Cost Explorer", "url": "https://console.aws.amazon.com/costmanagement/home" },
|
|
10
|
+
{ "label": "Health", "url": "https://health.aws.amazon.com/health/status" }
|
|
11
|
+
],
|
|
12
|
+
"supportedModes": ["api"],
|
|
13
|
+
"autoMode": "api",
|
|
14
|
+
"lines": [
|
|
15
|
+
{ "type": "text", "label": "Month spend", "scope": "overview", "primaryOrder": 1 },
|
|
16
|
+
{ "type": "progress", "label": "Monthly budget", "scope": "overview", "primaryOrder": 2 }
|
|
17
|
+
]
|
|
18
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>AzureAI</title><path clip-rule="evenodd" d="M16.233 0c.713 0 1.345.551 1.572 1.329.227.778 1.555 5.59 1.555 5.59v9.562h-4.813L14.645 0h1.588z" fill="url(#lobe-icons-azure-ai-0-_R_0_)" fill-rule="evenodd"></path><path d="M23.298 7.47c0-.34-.275-.6-.6-.6h-2.835a3.617 3.617 0 00-3.614 3.615v5.996h3.436a3.617 3.617 0 003.613-3.614V7.47z" fill="url(#lobe-icons-azure-ai-1-_R_0_)"></path><path clip-rule="evenodd" d="M16.233 0a.982.982 0 00-.989.989l-.097 18.198A4.814 4.814 0 0110.334 24H1.6a.597.597 0 01-.567-.794l7-19.981A4.819 4.819 0 0112.57 0h3.679-.016z" fill="url(#lobe-icons-azure-ai-2-_R_0_)" fill-rule="evenodd"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-azure-ai-0-_R_0_" x1="18.242" x2="14.191" y1="16.837" y2=".616"><stop stop-color="#712575"></stop><stop offset=".09" stop-color="#9A2884"></stop><stop offset=".18" stop-color="#BF2C92"></stop><stop offset=".27" stop-color="#DA2E9C"></stop><stop offset=".34" stop-color="#EB30A2"></stop><stop offset=".4" stop-color="#F131A5"></stop><stop offset=".5" stop-color="#EC30A3"></stop><stop offset=".61" stop-color="#DF2F9E"></stop><stop offset=".72" stop-color="#C92D96"></stop><stop offset=".83" stop-color="#AA2A8A"></stop><stop offset=".95" stop-color="#83267C"></stop><stop offset="1" stop-color="#712575"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-azure-ai-1-_R_0_" x1="19.782" x2="19.782" y1=".34" y2="23.222"><stop stop-color="#DA7ED0"></stop><stop offset=".08" stop-color="#B17BD5"></stop><stop offset=".19" stop-color="#8778DB"></stop><stop offset=".3" stop-color="#6276E1"></stop><stop offset=".41" stop-color="#4574E5"></stop><stop offset=".54" stop-color="#2E72E8"></stop><stop offset=".67" stop-color="#1D71EB"></stop><stop offset=".81" stop-color="#1471EC"></stop><stop offset="1" stop-color="#1171ED"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-azure-ai-2-_R_0_" x1="18.404" x2="3.236" y1=".859" y2="25.183"><stop stop-color="#DA7ED0"></stop><stop offset=".05" stop-color="#B77BD4"></stop><stop offset=".11" stop-color="#9079DA"></stop><stop offset=".18" stop-color="#6E77DF"></stop><stop offset=".25" stop-color="#5175E3"></stop><stop offset=".33" stop-color="#3973E7"></stop><stop offset=".42" stop-color="#2772E9"></stop><stop offset=".54" stop-color="#1A71EB"></stop><stop offset=".68" stop-color="#1371EC"></stop><stop offset="1" stop-color="#1171ED"></stop></linearGradient></defs></svg>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>AzureAI</title><path clip-rule="evenodd" d="M16.233 0c.713 0 1.345.551 1.572 1.329.227.778 1.555 5.59 1.555 5.59v9.562h-4.813L14.645 0h1.588z" fill-opacity=".5"></path><path d="M23.298 7.47c0-.34-.275-.6-.6-.6h-2.835a3.617 3.617 0 00-3.614 3.615v5.996h3.436a3.617 3.617 0 003.613-3.614V7.47z"></path><path clip-rule="evenodd" d="M16.233 0a.982.982 0 00-.989.989l-.097 18.198A4.814 4.814 0 0110.334 24H1.6a.597.597 0 01-.567-.794l7-19.981A4.819 4.819 0 0112.57 0h3.679-.016z"></path></svg>
|