smoke-budget-guard.js 1.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657
  1. 'use strict';
  2. const assert = require('assert');
  3. const { createBatchBudgetGuard } = require('../mcp/src/core/batch-budget-guard');
  4. async function main() {
  5. const calls = [];
  6. const context = { usageTraceId: 'usage_smoke_budget', reportId: 'report_smoke_budget' };
  7. const input = {
  8. budgetCny: 1,
  9. queryBillingImpl: async ({ operations }) => {
  10. calls.push(operations);
  11. return {
  12. status: 'ok',
  13. data: {
  14. balance: { availableQuota: 100 },
  15. estimate: { quota: 1000, amountCny: 1.2, operations },
  16. usage: { totals: { costCny: 0.8 } }
  17. }
  18. };
  19. }
  20. };
  21. const guard = createBatchBudgetGuard({
  22. input,
  23. context,
  24. operationFactory: () => [{ model: 'voc-social', path: 'search_notes', count: 1, priceCnyPerCall: 1.2, quotaPerCall: 1000 }]
  25. });
  26. const decision = await guard.beforeBatch({ keyword: '预算测试', batchIndex: 0 });
  27. assert.strictEqual(decision.allowed, false);
  28. assert.strictEqual(decision.status, 'blocked');
  29. assert.strictEqual(decision.budgetLimitCny, 1);
  30. assert.strictEqual(calls.length, 1);
  31. assert.strictEqual(guard.snapshot().keyword, '预算测试');
  32. const rechargeGuard = createBatchBudgetGuard({
  33. input: { budgetCny: 20, queryBillingImpl: async () => ({
  34. status: 'ok',
  35. data: {
  36. balance: { availableQuota: 10 },
  37. estimate: { quota: 1000, amountCny: 2, operations: [] },
  38. usage: { totals: { costCny: 0 } }
  39. }
  40. }) },
  41. context,
  42. operationFactory: () => [{ model: 'voc-social', path: 'search_notes', count: 1 }]
  43. });
  44. const rechargeDecision = await rechargeGuard.beforeBatch({ keyword: '余额测试' });
  45. assert.strictEqual(rechargeDecision.status, 'needs_recharge');
  46. assert.strictEqual(rechargeDecision.allowed, false);
  47. process.stdout.write('budget guard smoke ok\n');
  48. }
  49. main().catch(error => {
  50. process.stderr.write(`${error.stack || error}\n`);
  51. process.exitCode = 1;
  52. });