// ═══════════════════════════════════════ // 铸渊开发Agent · 成本守卫 + 统一插座 v1.0 // API调用计数 · 预算控制 · 输出格式校验 // ═══════════════════════════════════════ const fs = require("fs"); const path = require("path"); const CONSTITUTION = JSON.parse(fs.readFileSync(path.join(__dirname, "..", "agent-constitution.json"), "utf-8")); const { cost_guard, unified_interface } = CONSTITUTION; let _callCount = 0; let _budgetExceeded = false; function reset() { _callCount = 0; _budgetExceeded = false; } function getCallCount() { return _callCount; } function isBudgetExceeded() { return _budgetExceeded; } /** * 包裹模型调用——自动计数 */ function wrapModelCaller(rawCaller) { return async function(prompt, opts) { if (_budgetExceeded) { throw new Error(cost_guard.stop_message); } _callCount++; if (_callCount > cost_guard.max_api_calls_per_session) { _budgetExceeded = true; throw new Error(cost_guard.stop_message + " (已用 " + _callCount + " 次,上限 " + cost_guard.max_api_calls_per_session + ")"); } console.log("[CostGuard] API调用 #" + _callCount + "/" + cost_guard.max_api_calls_per_session); return rawCaller(prompt, opts); }; } /** * 统一校验——每个模块输出必须通过这把尺 */ function validateOutput(output) { const required = unified_interface.required_output_fields; const missing = required.filter(f => !(f in output)); if (missing.length > 0) { return { valid: false, error: "输出缺少必要字段: " + missing.join(", "), required, received: Object.keys(output) }; } // 类型校验 if (typeof output.ok !== "boolean") { return { valid: false, error: "ok 必须是 boolean,收到: " + typeof output.ok }; } return { valid: true }; } module.exports = { wrapModelCaller, validateOutput, reset, getCallCount, isBudgetExceeded };