Files
OmniRoute/tests/unit/quota-token-estimator.test.ts
Benson K B 2d50ec0789 feat(routing): add quota-aware provider scheduling — Phase 2 (#10126)
* feat(quota): Phase 2 adapters, reset timers, analytics, and dashboard API

* feat(routing): add quota-aware provider scheduling (opt-in)

* fix(db): rename migration to 148_provider_quota_state.sql

* fix(quota): harden quota state route, isolate phase2 tests, slim env diff

- route: requireManagementAuth + Zod body validation + buildErrorBody
  sanitization (Hard Rule #12); fix clearProviderQuotaState -> clearProviderQuota
- .env.example/ENVIRONMENT.md: drop ~20 foreign vars, keep only
  OMNIROUTE_QUOTA_AWARE_ROUTING (migration 148)
- tests/unit/quota-phase2.test.ts: DATA_DIR mkdtemp + resetDbInstance teardown

Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>

* chore(ci): fix docs-sync + eslint-suppression drift for quota branch

CI gates flagged on PR #10126 head 43335f07:
- migration counts in README/AGENTS/llm.txt were stale (145 -> 146)
- regenerate docs/reference/PROVIDER_REFERENCE.md (gen-provider-reference)
- sync root llm.txt body into all 42 i18n mirrors (headers preserved)
- prune eslint suppressions that no longer occur

--no-verify: pre-commit docs-sync was failing on a pre-existing
release-base artifact (changelog 3.8.49 vs package 3.8.50) — fixed by
the changelog entry in the prior commit; re-verify in CI.

* chore(skills): regenerate agent skills (add omni-settings)

Merge-integrity CI gate flagged a missing generated skill. Regenerated
with check:agent-skills-sync --apply: +omni-settings, 45 unchanged.

* fix(ci): resolve Fast Quality Gates regressions on quota branch

- check-migration-numbering: migration 148 (provider_quota_state) landed
  on this branch, so the KNOWN_GAPS allowlist entry is stale — remove it
  (stale-enforcement 6A.3: 'REMOVA a entrada')
- open-sse/utils/stream.ts: duplicate sseCommentsEnabled import from a
  bad merge (lines 31 + 77) — TS2300 duplicate identifier; drop the
  duplicate so the open-sse typecheck gate is back within baseline

* docs: sync migration count to 149 after release merge

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

* test(migrations): align 148 gap assertion after 148_provider_quota_state.sql landed

The phase-2 branch added 148_provider_quota_state.sql, and 148 was already
removed from KNOWN_GAPS in scripts/check/check-migration-numbering.mjs. The
frozen-allowlists assertion still expected 148 to be a gap, so it failed.
Flip the assertion to match the allowlist (same pattern as 143/147).

Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>

---------

Co-authored-by: benzntech <benzntech@users.noreply.github.com>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Co-authored-by: adevwithpurpose <adevwithpurpose@users.noreply.github.com>
Co-authored-by: diegosouzapw <diegosouza.pw@gmail.com>
2026-08-18 10:49:19 -03:00

84 lines
2.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test } from "node:test";
import assert from "node:assert/strict";
import { estimateChatTokenCost, estimateStringTokens } from "../../src/lib/quota/tokenEstimator";
test("estimateStringTokens: chars/4 heuristic", () => {
assert.equal(estimateStringTokens(""), 0);
assert.equal(estimateStringTokens("abcd"), 1);
assert.equal(estimateStringTokens("abcdefgh"), 2);
});
test("estimateChatTokenCost: sums message content strings", () => {
const cost = estimateChatTokenCost({
messages: [
{ role: "user", content: "Hello world, this is a test message" },
{ role: "assistant", content: "A shorter reply" },
],
});
assert.ok(cost.inputTokens > 0);
// total = input × 1.1 (over-provision) + output budget
assert.equal(cost.totalTokens, Math.ceil(cost.inputTokens * 1.1) + cost.outputTokens);
});
test("estimateChatTokenCost: includes system prompt", () => {
const withoutSystem = estimateChatTokenCost({
messages: [{ role: "user", content: "hi there" }],
});
const withSystem = estimateChatTokenCost({
system: "You are a helpful assistant with a fairly long system prompt to count",
messages: [{ role: "user", content: "hi there" }],
});
assert.ok(withSystem.inputTokens > withoutSystem.inputTokens);
});
test("estimateChatTokenCost: honors max_tokens as output budget", () => {
const cost = estimateChatTokenCost({
messages: [{ role: "user", content: "hi" }],
max_tokens: 2000,
});
assert.equal(cost.outputTokens, 2000);
});
test("estimateChatTokenCost: honors max_completion_tokens (Responses API)", () => {
const cost = estimateChatTokenCost({
messages: [{ role: "user", content: "hi" }],
max_completion_tokens: 500,
});
assert.equal(cost.outputTokens, 500);
});
test("estimateChatTokenCost: defaults output allowance when unset", () => {
const cost = estimateChatTokenCost({ messages: [{ role: "user", content: "hi" }] });
assert.equal(cost.outputTokens, 1024);
});
test("estimateChatTokenCost: handles multimodal content arrays", () => {
const cost = estimateChatTokenCost({
messages: [
{
role: "user",
content: [
{ type: "text", text: "Describe this image" },
{ type: "image_url", image_url: { url: "data:image/png;base64,xxx" } },
],
},
],
});
assert.ok(cost.inputTokens > 0);
});
test("estimateChatTokenCost: handles Responses API input array", () => {
const cost = estimateChatTokenCost({
input: [{ role: "user", text: "What is the capital of France" }],
});
assert.ok(cost.inputTokens > 0);
});
test("estimateChatTokenCost: never throws on malformed bodies", () => {
for (const bad of [null, undefined, {}, { messages: "nope" }, { messages: [null, 42] }]) {
const cost = estimateChatTokenCost(bad as Record<string, unknown>);
assert.ok(cost.totalTokens >= 0);
}
});