mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-11 01:13:02 +03:00
Compare commits
1 Commits
fix/12681-
...
fix/12749-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
27d643a9da |
1
changelog.d/fixes/12749-ollama-cloud-usage-cookie.md
Normal file
1
changelog.d/fixes/12749-ollama-cloud-usage-cookie.md
Normal file
@@ -0,0 +1 @@
|
||||
- fix(sse): parse Ollama Cloud's current usage markup (`$X of $Y used` aria-label, nested width style) (#12749)
|
||||
@@ -77,16 +77,36 @@ function normalizeOllamaCloudCookie(value: string): string {
|
||||
: trimmed;
|
||||
}
|
||||
|
||||
function clampPercent(pct: number): number | null {
|
||||
return Number.isFinite(pct) && pct >= 0 && pct <= 100 ? pct : null;
|
||||
}
|
||||
|
||||
function extractAriaLabelPercent(tagHeader: string): number | null {
|
||||
const directMatch = tagHeader.match(/(\d+(?:\.\d+)?)%\s*used/);
|
||||
if (directMatch) return clampPercent(toNumber(directMatch[1], Number.NaN));
|
||||
const ratioMatch = tagHeader.match(/\$\s*([0-9.]+)\s*of\s*\$\s*([0-9.]+)\s*used/i);
|
||||
if (!ratioMatch) return null;
|
||||
const used = toNumber(ratioMatch[1], Number.NaN);
|
||||
const total = toNumber(ratioMatch[2], Number.NaN);
|
||||
if (!Number.isFinite(used) || !Number.isFinite(total) || total <= 0) return null;
|
||||
return clampPercent((used / total) * 100);
|
||||
}
|
||||
|
||||
function extractWidthStylePercent(html: string): number | null {
|
||||
const styleMatches = html.matchAll(/style="([^"]*)"/g);
|
||||
for (const match of styleMatches) {
|
||||
const pct = toNumber(match[1].match(/(?:^|;)\s*width\s*:\s*([0-9.]+)%/)?.[1], Number.NaN);
|
||||
const clamped = clampPercent(pct);
|
||||
if (clamped !== null) return clamped;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function extractOllamaUsagePercent(trackHtml: string): number | null {
|
||||
const tagHeader = trackHtml.match(/^[^>]*/)?.[0] ?? "";
|
||||
const ariaMatch = tagHeader.match(/(\d+(?:\.\d+)?)%\s*used/);
|
||||
if (ariaMatch) {
|
||||
const pct = toNumber(ariaMatch[1], Number.NaN);
|
||||
if (Number.isFinite(pct) && pct >= 0 && pct <= 100) return pct;
|
||||
}
|
||||
const style = tagHeader.match(/style="([^"]*)"/)?.[1] ?? "";
|
||||
const pct = toNumber(style.match(/(?:^|;)\s*width\s*:\s*([0-9.]+)%/)?.[1], Number.NaN);
|
||||
return Number.isFinite(pct) && pct >= 0 && pct <= 100 ? pct : null;
|
||||
const ariaPercent = extractAriaLabelPercent(tagHeader);
|
||||
if (ariaPercent !== null) return ariaPercent;
|
||||
return extractWidthStylePercent(trackHtml);
|
||||
}
|
||||
|
||||
function parseOllamaCloudSettingsHtml(html: string): OllamaCloudUsage | null {
|
||||
|
||||
@@ -189,3 +189,79 @@ test("getUsageForProvider reports expired Ollama Cloud cookies on redirect", asy
|
||||
else process.env.OLLAMA_USAGE_COOKIE = originalCookie;
|
||||
}
|
||||
});
|
||||
|
||||
test("getUsageForProvider parses the current $X-of-$Y aria-label with nested width style (#12749)", async () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
const originalCookie = process.env.OLLAMA_USAGE_COOKIE;
|
||||
const originalOmniCookie = process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE;
|
||||
delete process.env.OLLAMA_USAGE_COOKIE;
|
||||
process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE = "__Secure-session=test-cookie";
|
||||
|
||||
globalThis.fetch = async () =>
|
||||
new Response(
|
||||
[
|
||||
'<span class="capitalize">pro</span>',
|
||||
'<div class="relative h-3 overflow-hidden rounded-full bg-neutral-200" data-usage-track aria-label="Monthly usage $60.01 of $60 used">',
|
||||
'<div class="flex h-full overflow-hidden bg-neutral-950" style="width: 100%; background: #ef4444;"></div>',
|
||||
'<span class="local-time" data-time="2026-06-22T15:00:00.000Z"></span>',
|
||||
"</div>",
|
||||
].join(""),
|
||||
{ status: 200, headers: { "content-type": "text/html" } }
|
||||
);
|
||||
|
||||
try {
|
||||
const result = (await usage.getUsageForProvider({
|
||||
id: "ollama-cloud-new-markup",
|
||||
provider: "ollama-cloud",
|
||||
apiKey: "ollama-chat-key",
|
||||
})) as { message?: string; quotas?: Record<string, { used: number }> };
|
||||
|
||||
assert.ok(
|
||||
result.quotas && Object.keys(result.quotas).length > 0,
|
||||
`expected quotas, got message: ${result.message}`
|
||||
);
|
||||
assert.equal(result.quotas!.session.used, 100);
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
if (originalCookie === undefined) delete process.env.OLLAMA_USAGE_COOKIE;
|
||||
else process.env.OLLAMA_USAGE_COOKIE = originalCookie;
|
||||
if (originalOmniCookie === undefined) delete process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE;
|
||||
else process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE = originalOmniCookie;
|
||||
}
|
||||
});
|
||||
|
||||
test("getUsageForProvider still finds width style on a nested child when no aria-label percent exists (#12749)", async () => {
|
||||
const originalFetch = globalThis.fetch;
|
||||
const originalCookie = process.env.OLLAMA_USAGE_COOKIE;
|
||||
const originalOmniCookie = process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE;
|
||||
delete process.env.OLLAMA_USAGE_COOKIE;
|
||||
process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE = "__Secure-session=test-cookie";
|
||||
|
||||
globalThis.fetch = async () =>
|
||||
new Response(
|
||||
[
|
||||
'<div class="relative h-3" data-usage-track aria-label="Weekly usage $12 of $60 used">',
|
||||
'<div class="flex h-full" style="width: 20%;"></div>',
|
||||
'<span class="local-time" data-time="2026-06-29T15:00:00.000Z"></span>',
|
||||
"</div>",
|
||||
].join(""),
|
||||
{ status: 200, headers: { "content-type": "text/html" } }
|
||||
);
|
||||
|
||||
try {
|
||||
const result = (await usage.getUsageForProvider({
|
||||
id: "ollama-cloud-nested-width",
|
||||
provider: "ollama-cloud",
|
||||
apiKey: "ollama-chat-key",
|
||||
})) as { quotas?: Record<string, { used: number }> };
|
||||
|
||||
// The aria-label ratio ($12 of $60 = 20%) is used, matching the nested style width fallback.
|
||||
assert.equal(result.quotas!.session.used, 20);
|
||||
} finally {
|
||||
globalThis.fetch = originalFetch;
|
||||
if (originalCookie === undefined) delete process.env.OLLAMA_USAGE_COOKIE;
|
||||
else process.env.OLLAMA_USAGE_COOKIE = originalCookie;
|
||||
if (originalOmniCookie === undefined) delete process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE;
|
||||
else process.env.OMNIROUTE_OLLAMA_USAGE_COOKIE = originalOmniCookie;
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user