70 lines
2.1 KiB
JavaScript
Raw Normal View History

// ═══════════════════════════════════════
// 铸渊开发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 };