Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat(project): add `project add evaluator code-based` by jariy17 · Pull Request #2144 · aws/agentcore-cli · GitHub
Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(project): add `project add evaluator code-based` by jariy17 · Pull Request #2144 · aws/agentcore-cli · GitHub
Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(project): add `project add evaluator code-based` by jariy17 · Pull Request #2144 · aws/agentcore-cli · GitHub
Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat(project): add `project add evaluator code-based` by jariy17 · Pull Request #2144 · aws/agentcore-cli · GitHub
Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(project): add `project add evaluator code-based` by jariy17 · Pull Request #2144 · aws/agentcore-cli · GitHub
Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); feat(project): add `project add evaluator code-based` by jariy17 · Pull Request #2144 · aws/agentcore-cli · GitHub
Skip to content

feat(project): add project add evaluator code-based - #2144

Draft
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based
Draft

feat(project): add project add evaluator code-based#2144
jariy17 wants to merge 7 commits into
refactorfrom
feat/project-add-evaluator-code-based

Conversation

@jariy17

@jariy17jariy17 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What

Adds agentcore project add evaluator code-based — declarative code-based evaluators via projects — plus enables agentcore project remove evaluator. Follows the project add pattern (#2034 / #2004 / #2035 / #1998 / #2037) and, after review, mirrors the runtime layering (thin handler → templates/evaluator.ts owns the registry + buildManagedEvaluatorSpec, paralleling buildRuntimeSpec).

No mode/selector flag — the mode is inferred from what you pass (mirrors CodeBasedConfigSchema's managed XOR external):

You passModeResult
--metric <library.Metric>managed · 3Pscaffolds a deepeval/autoevals Lambda from a template
(neither)managed · emptyscaffolds an empty @custom_code_based_evaluator() stub you fill in
--lambda-arn <arn>externalreferences an existing Lambda (no scaffold)

Command structure

agentcore project add evaluator add a custom evaluator to the current project
├── llm-as-a-judge existing — LLM prompted to score a session
└── code-based NEW — a Lambda that scores a session
agentcore project remove evaluator --name <name> NEW — enabled via the generic remove

agentcore project add evaluator code-based --help:

Usage: agentcore project add evaluator code-based [options]
add a code-based evaluator — a Lambda that scores a session. Pass a 3P metric,
an existing Lambda, or neither to scaffold an empty evaluator you fill in
Options:
--name <name> the name of the evaluator
--level <level> what to score: SESSION, TRACE, or TOOL_CALL
--metric <metric> 3P metric to scaffold as <library.Metric>,
e.g. deepeval.FaithfulnessMetric or autoevals.Factuality
--model <model> judge model for the 3P metric,
e.g. bedrock/anthropic.claude-3-5-sonnet-20240620-v1:0
--lambda-arn <lambda-arn> ARN of an existing Lambda that scores a session
--timeout-seconds <timeout-seconds> Lambda timeout in seconds (1-300)
--description <description> a description of what this evaluator measures
--kms-key-arn <kms-key-arn> customer-managed KMS key ARN to encrypt the evaluator
--tags <tags> tags to apply (JSON object of key/value strings)
-h, --help display help for command

Enforced in-handler (not shown by Commander): --name + --level required; exactly one of --metric/--lambda-arn; --metric must be <library>.<Class> where library ∈ {deepeval, autoevals} and Class is a single identifier; --model must be a Bedrock model id / inference-profile-or-foundation-model ARN (optionally bedrock/-prefixed) and requires --metric; --timeout-seconds/--model/--metric are managed-only. Managed auto-fills codeLocation=app/<name>, entrypoint=lambda_function.handler, per-library timeoutSeconds (deepeval 300, else 60), and additionalPolicies=["execution-role-policy.json"].

Commits

  1. c4430c03 feat — the command + 3 scaffold templates + remove evaluator
  2. baec1630 fix — guard app/<name> collisions (up-front, no partial writes)
  3. e7bc3675 fix — validate --metric class + require a Bedrock --model
  4. 9bd79980 fix — echo the inferred mode + caveats at add time
  5. 32a10ef9 refactor — share toPythonPackageName via fsUtils; DEFAULT_TIMEOUT const
  6. 853dcf86 refactor — move template knowledge into templates/evaluator.ts (runtime layering)

Testing

  • bun run build OK · bun test src/handlers/project src/core/project597 pass / 0 fail.
  • Cloud bug bash (5 parallel agents; 2 deployed to a non-prod account, us-west-2, then tore down): all 5 flows + a 13-case error matrix pass at the CLI/scaffold/synth layer. The managed evaluator synthesizes correctly into AWS::BedrockAgentCore::Evaluator + Lambda + role + permissions, and generated Python ast.parses for deepeval + autoevals (bedrock + openai branches). Full report shared separately.

Known issues surfaced by the cloud deploy (both OUTSIDE this PR)

The evaluator authoring + synth work; end-to-end project deploy is currently blocked by two pre-existing bugs, neither in this feature's code:

  1. Payments construct doesn't exist (feat(project): add payment resources #2120) — the vended src/assets/cdk/lib/cdk-stack.ts imports/instantiates AgentCorePayments, but no published @aws/agentcore-cdk version exports that name (alpha.49 and alpha.50 export AgentCorePaymentManager/Connector). So it's a template code bug, not a stale pin — a version bump can't fix it; the construct must be dropped or gated behind a spec payments-config check. tsc TS2305 → build/synth/deploy fail for every scaffolded project, evaluator or not. Owner: payments.
  2. L3 evaluator "Access denied for Lambda" (reproducible) — with the payments line removed, synth emits the full evaluator resource set and deploy reaches AWS::BedrockAgentCore::Evaluator, which fails CREATE_FAILED: "Access denied for Lambda function …". Confirmed across two runs (not a race): the lambda:InvokeFunction/GetFunction grants to bedrock-agentcore.amazonaws.com reach CREATE_COMPLETE ~9s before the evaluator, yet the control-plane access check still denies — a deterministic authorization-shape mismatch (likely a required SourceAccount/SourceArn condition) in @aws/agentcore-cdk's AgentCoreEvaluator. Owner: agentcore-cdk L3.

🤖 Draft — CLI/authoring layer is complete and green; hold merge until the two deploy blockers (payments #2120, agentcore-cdk L3) land.

@github-actionsgithub-actionsBot added the size/xl PR size: XL label Aug 28, 2026
@agentcore-devx-automationagentcore-devx-automationBot added agentcore-harness-reviewing AgentCore Harness review in progress claude-security-reviewing Claude Code /security-review in progress labels Aug 28, 2026

@agentcore-devx-automationagentcore-devx-automationBot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AgentCore Harness Review

Verdict: Looks good

Small, focused fix that surfaces two real footguns of the code-based evaluator scaffold:

  • Empty stub silently returns Pass for every session (verified against src/assets/evaluators/python-lambda/lambda_function.py, which returns label="Pass").
  • Managed code-based evaluators aren't yet provisioned by project deploy.

Logic in index.ts (lines 158–166) matches the commit message: the "returns Pass" note is gated on !hasLambda && !hasMetric, and the "not yet provisioned" note is gated on !hasLambda, so --lambda-arn (external) correctly prints neither.

Tests in index.test.ts use real temp directories via mkdtemp and drive the handler through the router — no excessive mocking — and cover both the stub and external paths. Telemetry isn't warranted here since this only adds informational stderr output, not a new feature.

Nothing blocking.

@agentcore-devx-automationagentcore-devx-automationBot removed the agentcore-harness-reviewing AgentCore Harness review in progress label Aug 28, 2026
@codecov-commenter

codecov-commenter commented Aug 28, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.31%. Comparing base (3d449c5) to head (9bd7998).

Additional details and impacted files
@@ Coverage Diff @@## refactor #2144 +/- ##
============================================
+ Coverage 97.29% 97.31% +0.01% 
============================================
Files 479 481 +2 Lines 29673 29865 +192 ============================================
+ Hits 28871 29063 +192 
Misses 802 802 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 28, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from 303c8db to 9bd7998CompareAugust 31, 2026 14:51
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/xl PR size: XL labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
const context: Record<string, unknown> = { Name: toPythonPackageName(flags["name"]) };

if (hasMetric) {
const raw = flags["metric"]!;

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use make this helper function and use zod here.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e78e9bc to 32a10efCompareAugust 31, 2026 17:33
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@@ -0,0 +1,15 @@
{

@jariy17jariy17Aug 31, 2026

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't want add an abstraction to generate common assets like this one due time constraints. We can look for this in the future.

@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
jariy17 added 7 commits August 31, 2026 19:38
Declarative code-based evaluators via projects. Mode is inferred from flags
(mirrors CodeBasedConfigSchema managed XOR external):
--lambda-arn -> external (BYO Lambda)
--metric <library.Metric> -> managed 3P (deepeval/autoevals), scaffolded
neither -> managed empty stub you fill in
Scaffolds app/<name>/ from ported evaluator templates (python/deepeval/autoevals
lambda), hardcodes codeLocation, and auto-wires additionalPolicies=
[execution-role-policy.json]. Also enables `project remove evaluator`.
…aluators
Runtimes, harnesses, and evaluators all scaffold into app/<name>, but the
duplicate-name guard is per-resource-type and the tree write happens outside
the rollback try/catch. An evaluator whose name matches an existing runtime/
harness dir (or a leftover from a removed evaluator) threw a raw 'File already
exists' mid-write and orphaned partial files. Fail up front with a clear
InputValidationError when app/<name> already exists.
…or code-based evaluators
- Reject a namespaced/multi-dot metric class (e.g. deepeval.metrics.Faithfulness)
that would render invalid Python; require a single class identifier.
- --model is Bedrock-only: accept a bare model id / inference-profile-or-
foundation-model ARN, optionally prefixed with bedrock/, validated via
isValidBedrockModelId (same forms the llm-as-a-judge handler accepts).
Non-Bedrock or slashless values now error instead of being silently dropped
(deepeval) or passed to the wrong client (autoevals).
- autoevals template prefixes bedrock/ for litellm routing now that Model is the
bare id.
Print notes after add: the empty stub returns Pass for every session until
implemented, and managed evaluators are scaffolded but not yet provisioned by
'project deploy' (no CDK/L3 support). External (--lambda-arn) prints neither.
…templates layer
Mirror the runtime layering: the handler now just parses/validates flags and
passes a ManagedEvaluatorScaffoldInput; templates/evaluator.ts owns the library
registry, per-library timeouts, render context, and buildManagedEvaluatorSpec
(parallels buildRuntimeSpec). Also adds "evaluator" to RemoveResourceInput.
…aluators
The L3 (@aws/agentcore-cdk) does provision spec.evaluators — synth emits
AWS::BedrockAgentCore::Evaluator + Lambda — so the note was inaccurate. Keep the
empty-stub 'returns Pass until implemented' note, which is still true.
@jariy17
jariy17force-pushed the feat/project-add-evaluator-code-based branch from e440cb5 to 7215450CompareAugust 31, 2026 19:41
@github-actionsgithub-actionsBot added size/l PR size: L and removed size/l PR size: L labels Aug 31, 2026
@agentcore-devx-automationagentcore-devx-automationBot added the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automationagentcore-devx-automationBot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 31, 2026
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/lPR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@jariy17@codecov-commenter