Skip to content

Commit 0dd936a

Browse files
christsoclaude
andcommitted
fix(core): resolve use_target chains in orchestrator for grader targets
The orchestrator's resolveTargetByName() now follows use_target chains before calling resolveTargetDefinition(). This fixes grader resolution when the grader target uses use_target delegation (e.g., grader → GRADER_TARGET → openrouter). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 3441f91 commit 0dd936a

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

packages/core/src/evaluation/orchestrator.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,22 @@ export async function runEvaluation(
356356
if (resolvedTargetsByName.has(name)) {
357357
return resolvedTargetsByName.get(name);
358358
}
359-
const definition = targetDefinitions.get(name);
359+
// Follow use_target chain to find the concrete definition
360+
let definition = targetDefinitions.get(name);
360361
if (!definition) {
361362
return undefined;
362363
}
364+
for (let depth = 0; depth < 5; depth++) {
365+
const useTarget = definition.use_target;
366+
if (typeof useTarget !== 'string' || useTarget.trim().length === 0) break;
367+
// Resolve ${{ ENV_VAR }} syntax
368+
const envMatch = useTarget.trim().match(/^\$\{\{\s*([A-Z0-9_]+)\s*\}\}$/i);
369+
const resolvedName = envMatch ? (envLookup[envMatch[1]] ?? '') : useTarget.trim();
370+
if (resolvedName.length === 0) break;
371+
const next = targetDefinitions.get(resolvedName);
372+
if (!next) break;
373+
definition = next;
374+
}
363375
const resolved = resolveTargetDefinition(definition, envLookup, evalFilePath);
364376
resolvedTargetsByName.set(name, resolved);
365377
return resolved;

0 commit comments

Comments
 (0)