Aller au contenu principal
Version: 1.0.0

Tester un budget financier sans appel payant

Cet exercice vérifie le registre du SDK, sans modèle, sans clé et sans facture. Les montants sont un contrat d'essai, pas un tarif fournisseur. Installez le SDK JavaScript ou le SDK Python.

JavaScript​

Enregistrez ce programme dans budget-test.mjs puis lancez node budget-test.mjs. Le répertoire temporaire appartient à cet exercice.

import assert from "node:assert/strict";
import { mkdtempSync, rmSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
import { createSqliteProviderBudget } from "@touba/sdk/budget/sqlite";

const directory = mkdtempSync(join(tmpdir(), "touba-budget-example-"));
const options = { filename: join(directory, "costs.sqlite"),
budgetId: "test-operation", currency: "USD", limitMicros: 100n };
const quote = { basis: "upper_bound", maxCostMicros: 60n, currency: "USD",
tariffId: "exercise-contract", tariffDate: "2026-10-18" };
let budget;
try {
budget = createSqliteProviderBudget(options);
const attempt = budget.reserve(quote);
budget.settle(attempt, { kind: "unknown" });
assert.equal(budget.snapshot().remainingMicros, 40n);
assert.throws(() => budget.reserve(quote),
error => error.code === "ProviderCostBudgetExceeded");
budget.close();
budget = createSqliteProviderBudget(options);
assert.equal(budget.snapshot().remainingMicros, 40n);
assert.equal(budget.listAttempts({ status: "unknown" })[0].id, attempt);
// Test evidence only; production reconciliation requires provider evidence.
budget.settle(attempt, { kind: "reported", costMicros: 20n });
assert.equal(budget.snapshot().remainingMicros, 80n);
console.log("BUDGET_OK");
} finally {
budget?.close();
rmSync(directory, { recursive: true, force: true });
}

Python​

Enregistrez ce programme dans budget_test.py puis lancez-le avec le Python du projet où le SDK est installé. Il vérifie exactement le même cycle.

from pathlib import Path
from tempfile import TemporaryDirectory
from touba_sdk import ToubaAgentDecisionProviderError
from touba_sdk.budget.sqlite import create_sqlite_provider_budget

with TemporaryDirectory(prefix="touba-budget-example-") as directory:
options = dict(filename=Path(directory) / "costs.sqlite",
budget_id="test-operation", currency="USD", limit_micros=100)
quote = dict(basis="upper_bound", max_cost_micros=60, currency="USD",
tariff_id="exercise-contract", tariff_date="2026-10-18")
budget = create_sqlite_provider_budget(**options)
try:
attempt = budget.reserve(quote)
budget.settle(attempt, {"kind": "unknown"})
assert budget.snapshot()["remaining_micros"] == 40
try:
budget.reserve(quote)
except ToubaAgentDecisionProviderError as error:
assert error.code == "ProviderCostBudgetExceeded"
else:
raise AssertionError("Expected a monetary budget refusal")
budget.close()
budget = create_sqlite_provider_budget(**options)
assert budget.snapshot()["remaining_micros"] == 40
assert budget.list_attempts(status="unknown")[0]["id"] == attempt
# Test evidence only; production reconciliation requires provider evidence.
budget.settle(attempt, {"kind": "reported", "cost_micros": 20})
assert budget.snapshot()["remaining_micros"] == 80
print("BUDGET_OK")
finally:
budget.close()

Lire le résultat​

BUDGET_OK confirme que l'usage inconnu garde sa réservation, que le dépassement est refusé et que la reprise conserve le solde. Seule une information d'usage explicite libère ensuite la différence. Cela teste la comptabilité, pas un appel LLM ni la justesse d'un tarif. Pour protéger de vrais appels, suivez le guide des coûts fournisseurs.