feat: add fail-closed Aider development skill
This commit is contained in:
@@ -346,6 +346,26 @@ function normalizeSessionMessageCount(value) {
|
||||
return Math.floor(parsed);
|
||||
}
|
||||
|
||||
export function resolveRequiredCodeExecutor(userMessage) {
|
||||
const metadata = userMessage?.metadata;
|
||||
const runMetadata = metadata?.[RUN_METADATA_KEY] ?? metadata?.agentRun ?? {};
|
||||
const executor = String(runMetadata?.executor ?? '').trim().toLowerCase();
|
||||
return ['aider', 'openhands'].includes(executor) ? executor : null;
|
||||
}
|
||||
|
||||
export function assertRequiredCodeExecutorAvailable(requiredExecutor, toolGatewayStatus) {
|
||||
if (!requiredExecutor) return;
|
||||
const executors = Array.isArray(toolGatewayStatus?.executors)
|
||||
? toolGatewayStatus.executors.map((item) => String(item).trim().toLowerCase())
|
||||
: [];
|
||||
if (!toolGatewayStatus?.enabled || !executors.includes(requiredExecutor)) {
|
||||
const error = new Error(`必需执行器 ${requiredExecutor} 不可用,任务已停止且不会回退`);
|
||||
error.code = 'REQUIRED_EXECUTOR_UNAVAILABLE';
|
||||
error.retryable = false;
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
function getRunOptionsFromMessage(userMessage) {
|
||||
const metadata = userMessage?.metadata;
|
||||
const runMetadata = metadata?.[RUN_METADATA_KEY] ?? metadata?.agentRun ?? {};
|
||||
@@ -358,6 +378,7 @@ function getRunOptionsFromMessage(userMessage) {
|
||||
return {
|
||||
toolMode,
|
||||
taskType: normalizeTaskType(runMetadata?.taskType ?? metadata?.taskType),
|
||||
requiredExecutor: resolveRequiredCodeExecutor(userMessage),
|
||||
forceDeepReasoning: runMetadata?.forceDeepReasoning === true || metadata?.forceDeepReasoning === true,
|
||||
validation: normalizeToolGatewayValidation(runMetadata?.validation ?? metadata?.toolGatewayValidation),
|
||||
sessionMessageCount: normalizeSessionMessageCount(
|
||||
@@ -859,6 +880,7 @@ export function createAgentRunGateway({
|
||||
let userMessage = safeJsonParse(row.user_message_json, {});
|
||||
const runOptions = getRunOptionsFromMessage(userMessage);
|
||||
const toolGatewayStatus = toolGateway?.getStatus ? toolGateway.getStatus() : null;
|
||||
assertRequiredCodeExecutorAvailable(runOptions.requiredExecutor, toolGatewayStatus);
|
||||
let disclosureDecision = null;
|
||||
try {
|
||||
disclosureDecision = systemDisclosurePolicyService?.evaluate?.({
|
||||
@@ -1037,6 +1059,17 @@ export function createAgentRunGateway({
|
||||
cwd: workingDir,
|
||||
timeoutMs: runTimeoutMs,
|
||||
});
|
||||
if (
|
||||
runOptions.requiredExecutor &&
|
||||
String(result?.executor ?? '').trim().toLowerCase() !== runOptions.requiredExecutor
|
||||
) {
|
||||
const error = new Error(
|
||||
`执行器不匹配:要求 ${runOptions.requiredExecutor},实际 ${result?.executor ?? 'unknown'}`,
|
||||
);
|
||||
error.code = 'REQUIRED_EXECUTOR_MISMATCH';
|
||||
error.retryable = false;
|
||||
throw error;
|
||||
}
|
||||
await appendEvent(runId, 'tool_gateway_result', {
|
||||
executor: result.executor ?? null,
|
||||
dryRun: Boolean(result.dryRun),
|
||||
|
||||
Reference in New Issue
Block a user