Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
"dependencies": {
"@aws-cdk/toolkit-lib": "1.38.2",
"@aws-sdk/client-bedrock-agent": "^3.1092.0",
"@aws-sdk/client-bedrock-agentcore": "^3.1129.0",
"@aws-sdk/client-bedrock-agentcore": "^3.1135.0",
"@aws-sdk/client-bedrock-agentcore-control": "^3.1129.0",
"@aws-sdk/client-cloudformation": "^3.1092.0",
"@aws-sdk/client-cloudwatch-logs": "^3.1092.0",
Expand Down
11 changes: 10 additions & 1 deletion src/core/eval.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1003,7 +1003,10 @@ export class EvalClient implements CoreEvalClient {
await evaluatorKmsKeys(input.evaluatorIds ?? [], control),
// Read only to widen the write scope to the chosen destination; the
// request object below still gets the caller's object untouched.
{ outputConfig: input.outputConfig },
{
outputConfig: input.outputConfig,
logGroupNamePrefixes: logGroupNamePrefixesOf(dataSourceConfig),
},
)
).roleArn;

Expand Down Expand Up @@ -2116,6 +2119,12 @@ function logGroupNamesOf(dataSourceConfig: DataSourceConfig): string[] {
: [];
}

function logGroupNamePrefixesOf(dataSourceConfig: DataSourceConfig): string[] {
return "cloudWatchLogs" in dataSourceConfig
? (dataSourceConfig.cloudWatchLogs?.logGroupNamePrefixes ?? [])
: [];
}

// runtimeIdFromLogGroup recovers the runtime id embedded in a log group path
// produced by runtimeLogGroup, so an update can re-derive dataSourceConfig for a
// new --endpoint without the caller passing --agent again. Returns undefined for
Expand Down
14 changes: 12 additions & 2 deletions src/core/onlineEvalExecutionRole.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,14 +112,18 @@ export function executionPolicy(
logGroupNames: string[],
kmsKeyArns: string[],
outputConfig?: OnlineEvalResultDestination,
logGroupNamePrefixes: string[] = [],
): string {
const logs = `arn:aws:logs:${region}:${accountId}:log-group`;
const spansArn = `${logs}:aws/spans`;
// Scope to the runtime prefix rather than the exact endpoint log group: the
// service validates query access at the runtime level (all of a runtime's
// endpoints share the `...-<runtimeId>-<endpoint>` naming), and a policy
// pinned to one endpoint is rejected as insufficient.
const sampledArns = logGroupNames.map((name) => `${logs}:${runtimeLogGroupPrefix(name)}*`);
const sampledArns = [
...logGroupNames.map((name) => `${logs}:${runtimeLogGroupPrefix(name)}*`),
...logGroupNamePrefixes.map((prefix) => `${logs}:${prefix}*`),
];
return JSON.stringify({
Version: "2012-10-17",
Statement: [
Expand Down Expand Up @@ -220,6 +224,7 @@ export function scopePolicyName(policyDocument: string): string {
export type GrantScopeOptions = {
roleName?: string;
outputConfig?: OnlineEvalResultDestination;
logGroupNamePrefixes?: string[];
};

// grantOnlineEvalScope creates the execution role for `configName` if it does not
Expand All @@ -232,7 +237,11 @@ export async function grantOnlineEvalScope(
region: string,
logGroupNames: string[],
kmsKeyArns: string[] = [],
{ roleName = onlineEvalExecutionRoleName(configName), outputConfig }: GrantScopeOptions = {},
{
roleName = onlineEvalExecutionRoleName(configName),
outputConfig,
logGroupNamePrefixes,
}: GrantScopeOptions = {},
): Promise<{ roleArn: string; policyName: string }> {
let roleArn: string;
try {
Expand All @@ -256,6 +265,7 @@ export async function grantOnlineEvalScope(
logGroupNames,
kmsKeyArns,
outputConfig,
logGroupNamePrefixes,
);
const policyName = scopePolicyName(policyDocument);
await iam.send(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,4 @@
"resultDestination": "SOURCE_LOG_GROUP"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,15 @@ describe("eval batch-evaluation (fixture-backed)", () => {
}, 180_000);

test("evaluate submits a job with a customer-supplied output config", async () => {
// The StartBatchEvaluation fixture is keyed by the full SDK request, so this
// also verifies that raw prefix selectors and session trace filters pass
// through the command handler unchanged.
const stdout = await run([
"eval",
"batch-evaluation",
"evaluate",
"--agent",
FIXTURE_EVAL_AGENT,
"--data-source-config",
'{"cloudWatchLogs":{"logGroupNamePrefixes":["/aws/bedrock-agentcore/runtimes/support_agent-"],"serviceNames":["support_agent.DEFAULT"],"filterConfig":{"sessionTraceIds":[{"sessionId":"session-123","traceIds":["4bf92f3577b34da6a3ce929d0e0e4736"]}]}}}',
"--evaluators",
"Builtin.Helpfulness",
"--name",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@
"logGroupName": "/aws/bedrock-agentcore/evaluations/results/agentcore_cli_online_eval_kms-15ciiv2UoV"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"serviceNames": [
"testAgent_Agent.DEFAULT"
],
"logGroupNames": [
"/aws/bedrock-agentcore/runtimes/testAgent_Agent-wm9hYBD93Y-DEFAULT"
"logGroupNamePrefixes": [
"/aws/bedrock-agentcore/runtimes/testAgent_Agent-"
]
}
},
Expand All @@ -40,4 +40,4 @@
}
},
"evaluationExecutionRoleArn": "arn:aws:iam::725476964917:role/AgentCoreOnlineEval-agentcore_cli_online_eval_kms"
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
6 changes: 4 additions & 2 deletions src/handlers/eval/online-eval/online-eval.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -454,8 +454,10 @@ describe("execution role KMS scoping", () => {
"create",
"--name",
KMS_CONFIG_NAME,
"--agent",
FIXTURE_AGENT_ID,
// The PutRolePolicy fixture is keyed by the complete generated policy.
// Using a prefix source here verifies the default role grants that prefix.
"--data-source-config",
'{"cloudWatchLogs":{"logGroupNamePrefixes":["/aws/bedrock-agentcore/runtimes/testAgent_Agent-"],"serviceNames":["testAgent_Agent.DEFAULT"]}}',
// Builtin.Correctness is backed by the hand-authored fixture carrying a
// kmsKeyArn; Builtin.Helpfulness carries none, so this covers both arms of
// the resolution in one create.
Expand Down
12 changes: 10 additions & 2 deletions src/handlers/eval/sessionSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,18 @@ Accepts inline JSON, file://<path>, or - to read stdin.
JSON syntax:
{
"cloudWatchLogs": {
"logGroupNames": ["string", ...], // [required] groups holding the traces
"logGroupNames": ["string", ...], // exact names; maximum 10
"logGroupNamePrefixes": ["string", ...], // or match by prefix; maximum 5
"serviceNames": ["string", ...], // e.g. "my_agent.DEFAULT"
"filterConfig": {
"sessionIds": ["string", ...],
"sessionTraceIds": [
{
"sessionId": "string", // [required] session containing the traces
"traceIds": ["string", ...] // [required] up to 100 trace IDs
},
...
],
"timeRange": {
"startTime": "timestamp",
"endTime": "timestamp"
Expand All @@ -35,7 +43,7 @@ API reference:
https://docs.aws.amazon.com/bedrock-agentcore/latest/APIReference/API_DataSourceConfig.html

Example:
--data-source-config '{"cloudWatchLogs":{"logGroupNames":["/aws/bedrock-agentcore/runtimes/support_agent-AbC123XyZ9-DEFAULT"],"serviceNames":["support_agent.DEFAULT"],"filterConfig":{"sessionIds":["session-123"]}}}'`;
--data-source-config '{"cloudWatchLogs":{"logGroupNamePrefixes":["/aws/bedrock-agentcore/runtimes/support_agent-"],"serviceNames":["support_agent.DEFAULT"],"filterConfig":{"sessionTraceIds":[{"sessionId":"session-123","traceIds":["4bf92f3577b34da6a3ce929d0e0e4736"]}]}}}'`;

export class SessionSource {
static readonly flags = [
Expand Down
Loading