Add evolver resource manager

This commit is contained in:
Trae AI 2026-05-25 23:52:49 +08:00
parent 64f26c7b56
commit 5f09f19726
3 changed files with 292 additions and 0 deletions

View file

@ -1,2 +1,3 @@
export * from './types.js';
export * from './metric-evaluator.js';
export * from './resource-manager.js';

View file

@ -0,0 +1,100 @@
import type { ResourceBudget, ResourceUsage, VariantSpec } from './types.js';
export interface ResourceUseRequest {
variant: VariantSpec;
requestedUsage: ResourceUsage;
activeRuns: number;
activeHighRiskVariants: number;
}
export interface ResourceDegradedPlan {
reduceCandidateCount: boolean;
pauseLowPriorityGoals: boolean;
stopNewExploration: boolean;
}
export interface ResourceDecision {
allowed: boolean;
reason:
| 'within-budget'
| 'duration-budget-exceeded'
| 'compute-budget-exceeded'
| 'api-cost-budget-exceeded'
| 'storage-budget-exceeded'
| 'concurrency-limit-reached'
| 'high-risk-variant-quota-exhausted';
degradedPlan?: ResourceDegradedPlan;
}
export function decideResourceUse(
request: ResourceUseRequest,
budget: ResourceBudget,
currentUsage: ResourceUsage,
): ResourceDecision {
if (request.activeRuns >= budget.maxConcurrency) {
return deny('concurrency-limit-reached', {
reduceCandidateCount: false,
pauseLowPriorityGoals: true,
stopNewExploration: false,
});
}
if (
request.variant.riskLevel === 'high' &&
request.activeHighRiskVariants >= budget.maxHighRiskVariants
) {
return deny('high-risk-variant-quota-exhausted', {
reduceCandidateCount: false,
pauseLowPriorityGoals: false,
stopNewExploration: true,
});
}
const projectedUsage = addResourceUsage(currentUsage, request.requestedUsage);
if (projectedUsage.durationMs > budget.maxDurationMs) {
return deny('duration-budget-exceeded', budgetDegradation());
}
if (projectedUsage.computeUnits > budget.maxComputeUnits) {
return deny('compute-budget-exceeded', budgetDegradation());
}
if (projectedUsage.apiCostUsd > budget.maxApiCostUsd) {
return deny('api-cost-budget-exceeded', budgetDegradation());
}
if (projectedUsage.storageBytes > budget.maxStorageBytes) {
return deny('storage-budget-exceeded', budgetDegradation());
}
return {
allowed: true,
reason: 'within-budget',
};
}
function deny(reason: ResourceDecision['reason'], degradedPlan: ResourceDegradedPlan): ResourceDecision {
return {
allowed: false,
reason,
degradedPlan,
};
}
function addResourceUsage(currentUsage: ResourceUsage, requestedUsage: ResourceUsage): ResourceUsage {
return {
durationMs: currentUsage.durationMs + requestedUsage.durationMs,
computeUnits: currentUsage.computeUnits + requestedUsage.computeUnits,
apiCostUsd: currentUsage.apiCostUsd + requestedUsage.apiCostUsd,
storageBytes: currentUsage.storageBytes + requestedUsage.storageBytes,
};
}
function budgetDegradation(): ResourceDegradedPlan {
return {
reduceCandidateCount: true,
pauseLowPriorityGoals: false,
stopNewExploration: false,
};
}

View file

@ -0,0 +1,191 @@
import { describe, expect, it } from 'vitest';
import { decideResourceUse } from '../../../src/core/evolver/index.js';
import type { ResourceBudget, ResourceUsage, VariantSpec } from '../../../src/core/evolver/index.js';
const budget: ResourceBudget = {
maxDurationMs: 1000,
maxComputeUnits: 10,
maxApiCostUsd: 1,
maxStorageBytes: 2048,
maxConcurrency: 2,
maxHighRiskVariants: 1,
};
const currentUsage: ResourceUsage = {
durationMs: 100,
computeUnits: 2,
apiCostUsd: 0.1,
storageBytes: 256,
};
function variant(overrides: Partial<VariantSpec> = {}): VariantSpec {
return {
id: 'variant-parameter-1',
planId: 'plan-1',
mutationType: 'parameter',
description: 'Adjust topK',
patch: {
operations: [
{
op: 'setParameter',
path: 'retrieval.topK',
previousValue: 5,
nextValue: 8,
},
],
},
expectedGain: [
{
metricId: 'task_success_rate',
expectedDelta: 0.05,
direction: 'increase',
},
],
riskLevel: 'low',
rollbackPlan: {
strategy: 'restore-previous-parameters',
operations: [
{
op: 'setParameter',
path: 'retrieval.topK',
previousValue: 8,
nextValue: 5,
},
],
},
provenance: [
{
source: 'synthetic-benchmark',
reference: 'run-1',
capturedAt: '2026-05-25T00:00:00.000Z',
},
],
...overrides,
};
}
describe('decideResourceUse', () => {
it('allows a request when projected resource use stays within budget', () => {
const decision = decideResourceUse(
{
variant: variant(),
requestedUsage: {
durationMs: 300,
computeUnits: 3,
apiCostUsd: 0.2,
storageBytes: 512,
},
activeRuns: 1,
activeHighRiskVariants: 0,
},
budget,
currentUsage,
);
expect(decision).toEqual({
allowed: true,
reason: 'within-budget',
});
});
it('denies a request when projected API cost exceeds budget', () => {
const decision = decideResourceUse(
{
variant: variant(),
requestedUsage: {
durationMs: 100,
computeUnits: 1,
apiCostUsd: 1,
storageBytes: 128,
},
activeRuns: 0,
activeHighRiskVariants: 0,
},
budget,
currentUsage,
);
expect(decision).toEqual({
allowed: false,
reason: 'api-cost-budget-exceeded',
degradedPlan: {
reduceCandidateCount: true,
pauseLowPriorityGoals: false,
stopNewExploration: false,
},
});
});
it('denies a request when concurrency limit is reached', () => {
const decision = decideResourceUse(
{
variant: variant(),
requestedUsage: {
durationMs: 100,
computeUnits: 1,
apiCostUsd: 0,
storageBytes: 128,
},
activeRuns: 2,
activeHighRiskVariants: 0,
},
budget,
currentUsage,
);
expect(decision).toEqual({
allowed: false,
reason: 'concurrency-limit-reached',
degradedPlan: {
reduceCandidateCount: false,
pauseLowPriorityGoals: true,
stopNewExploration: false,
},
});
});
it('denies a high-risk request when high-risk quota is exhausted', () => {
const decision = decideResourceUse(
{
variant: variant({
id: 'variant-structure-1',
mutationType: 'structure',
riskLevel: 'high',
patch: {
operations: [
{
op: 'proposeStructureChange',
planPath: 'docs/aegis/plans/structure-change.md',
summary: 'Split evaluator into a plugin pipeline',
},
],
},
rollbackPlan: {
strategy: 'manual-review-required',
operations: [],
},
}),
requestedUsage: {
durationMs: 100,
computeUnits: 1,
apiCostUsd: 0,
storageBytes: 128,
},
activeRuns: 0,
activeHighRiskVariants: 1,
},
budget,
currentUsage,
);
expect(decision).toEqual({
allowed: false,
reason: 'high-risk-variant-quota-exhausted',
degradedPlan: {
reduceCandidateCount: false,
pauseLowPriorityGoals: false,
stopNewExploration: true,
},
});
});
});