Skip to content

Commit 69fb6dd

Browse files
wilmatosakshsehwmatosjrgithub-advanced-security[bot]edfragas
authored
Enhance event-driven-claims-agent: cost routing, deterministic execution, docs (#1761)
* feat(usecases): it-incident-response * add jira integration * fix minor memory usage points * docs: add IT incident response agent project docs and assets * config: add AgentCore project configuration and schema context * infra: add CDK project for AgentCore L3 construct deployment * feat: add Strands agent application (runtime, memory, MCP client, model) * feat: add Lambda functions for tools, infra providers, and ticket trigger * feat: add tool schemas, seed data, and knowledge base runbooks * chore: add deployment, evaluation, and ticket utility scripts * docs: comply with use-case README template (add details table and disclaimer) * chore: allow esbuild install script in CDK project * fix: create S3 Vectors bucket+index for KB (CFN does not auto-create) The Bedrock KnowledgeBase CloudFormation resource with type S3_VECTORS requires a pre-existing vector bucket and index. Passing an empty s3VectorsConfiguration fails schema validation. The console's 'quick create' auto-provisions these, but CloudFormation does not. Changes: - Import aws-cdk-lib/aws-s3vectors - Create CfnVectorBucket (named per account+region) - Create CfnIndex (float32, 1024 dims, cosine, no metadata keys) - Wire IndexArn, IndexName, VectorBucketArn into KB storageConfiguration - Grant KB role s3vectors:* actions on the vector index - Add removalPolicy to bucket+index - Add troubleshooting row to README - Deleted the ROLLBACK_COMPLETE stack to unblock next deploy * fix: resolve deploy issues (template envsubst, target name, IndexName removal) - aws-targets.json.template: fix envsubst-incompatible default syntax (${AWS_REGION:-us-west-2} → ${AWS_REGION}), change name 'dev' → 'default' - scripts/deploy.sh: export AWS_REGION with default before envsubst runs - infra-construct.ts: remove IndexName from s3VectorsConfiguration (caused CFN 'oneOf 2 subschemas matched' validation error — only IndexArn + VectorBucketArn are needed for BYO S3 Vectors) - deployed-state.json: updated by successful deploy * docs: update Quickstart to lead with deploy.sh as primary path * chore: stop tracking deployed-state.json (deployment-specific, not shared) * refactor(auth): rename OAUTH_PROVIDER_NAME to GATEWAY_OAUTH_PROVIDER_NAME Scope auth env vars per boundary for clarity: - OAUTH_PROVIDER_NAME -> GATEWAY_OAUTH_PROVIDER_NAME - GATEWAY_AUDIENCE -> GATEWAY_OAUTH_AUDIENCE Code maintains backward-compat fallback to legacy names. CDK injects new names into Runtime env vars at deploy. .env.example and agentcore/.env.local.example updated with boundary labels (Boundary 2, Boundary 3). * docs(auth): add authentication boundary guide New docs/authentication-guide.md explains the 3 auth boundaries: 1. Runtime Inbound (SigV4 vs CUSTOM_JWT) 2. Gateway Outbound (AWS_IAM vs CUSTOM_JWT M2M) 3. Jira Outbound (USER_FEDERATION 3LO) Covers: conceptual overview, env var reference, local dev implications, troubleshooting, and why all 3 patterns exist. * docs: fix local dev ports, CLI commands, and env var references README.md: - Add Port Mapping section (8081=Web UI, 8082=Runtime container) - Add troubleshooting entry for workload access token error - Fix agentcore invoke --dev (invalid) -> agentcore dev prompt - Update config table to use GATEWAY_OAUTH_* var names docs/custom-jwt-auth-upgrade.md: - Update all OAUTH_PROVIDER_NAME -> GATEWAY_OAUTH_PROVIDER_NAME - Update all GATEWAY_AUDIENCE -> GATEWAY_OAUTH_AUDIENCE docs/ARCHITECTURE.md: - Wrap ASCII diagrams in <details> tags for readability * Fix S3 Vectors Knowledge Base schema: remove indexName from s3VectorsConfiguration CloudFormation's AWS::Bedrock::KnowledgeBase type with S3_VECTORS storage has a schema constraint (oneOf) that rejects when both indexArn and indexName are provided. Pass only vectorBucketArn + indexArn to satisfy the schema. The indexName is implicit in the indexArn and Bedrock manages metadata internally during ingestion, so it's not needed in the configuration. Fixes: Properties validation failed - 'only 1 subschema matches out of 2' Verified: Stack now deploys successfully with CREATE_COMPLETE status * feat: migrate online eval to declarative agentcore.json Remove the custom resource workaround for Online Evaluation. The AgentCoreOnlineEvaluationConfig L3 construct (@aws/agentcore-cdk v0.1.0-alpha.34+) now handles dependency ordering automatically. Changes: - Delete lambdas/infra/online_eval_provider.py (custom resource Lambda) - Remove SKIP_ONLINE_EVAL logic from cdk-stack.ts and bin/cdk.ts - Online eval is now purely declarative via agentcore.json onlineEvalConfigs[] - To disable: set onlineEvalConfigs to [] in agentcore.json Standards-Consulted: std.cdk.prefer-declarative Standards-Gaps: none Standards-Proposed: none * fix: align model IDs with available Bedrock models Update all model ID references to use the exact identifiers from `aws bedrock list-foundation-models`: - AGENT_MODEL_ID: us.anthropic.claude-sonnet-4-6 (not -20250929-v1:0) - FAST_MODEL_ID: us.anthropic.claude-3-5-haiku-20241022-v1:0 - JUDGE_MODEL_ID: us.anthropic.claude-sonnet-4-6 The previous IDs (with -20250929-v1:0 suffix) were invalid and caused runtime ValidationException on agent invocation. Standards-Consulted: std.config.model-id-consistency, std.bedrock.verify-model-id-format Standards-Gaps: none Standards-Proposed: std.config.model-id-consistency, std.bedrock.verify-model-id-format, std.bedrock.validate-model-before-deploy * fix: add --target dev to all agentcore CLI commands This project uses a named target 'dev' in aws-targets.json (not the default target). All CLI invocations must explicitly pass --target dev. Standards-Consulted: std.deploy.target-dev Standards-Gaps: none Standards-Proposed: std.deploy.target-dev * docs: overhaul documentation to describe current state only - Remove SKIP_ONLINE_EVAL references throughout - Fix model IDs in all documentation - Remove .kiro references from public docs - Merge duplicate Online Eval sections in README - Fix GUARDRAIL_ID default (auto-creates, not skips) - Fix target name in troubleshooting (dev, not default) - Add --target dev to all documented deploy commands - Add Declarative vs Imperative section to ARCHITECTURE.md - Remove stale development process docs (8 root-level .md files) - Pad all README tables for aligned vertical bars Standards-Consulted: std.docs.current-state-only, std.deploy.target-dev, std.config.model-id-consistency Standards-Gaps: none Standards-Proposed: std.docs.current-state-only * chore: update agentcore config and CDK dependencies - agentcore.json: add onlineEvalConfigs, policyEngines, gateway config - aws-targets.json.template: minor format fix - CDK packages: update @aws/agentcore-cdk dependency range Standards-Consulted: std.cdk.prefer-declarative, std.deploy.target-dev Standards-Gaps: none Standards-Proposed: none * feat: improve agent resilience and MCP client handling - main.py: add graceful degradation when MCP tools unavailable, safe fallback to LLM-only mode on tool initialization failure - mcp_client/client.py: add get_all_mcp_clients_safe() with error collection instead of hard failure - trigger: minor fix - show_ticket.sh: minor fix Standards-Consulted: std.agentcore.mcp-sigv4-auth Standards-Gaps: none Standards-Proposed: none * feat: add end-to-end test script scripts/test-e2e.sh publishes a ticket to SNS, polls DynamoDB for resolution (10s intervals, 120s timeout), and asserts status=Resolved with a non-empty resolution_comment. Exits 0 on pass, 1 on fail. Usage: ./scripts/test-e2e.sh # sample ticket ./scripts/test-e2e.sh /path/to/ticket.json # custom ticket Standards-Consulted: std.deploy.target-dev Standards-Gaps: none Standards-Proposed: none * feat: upgrade FAST_MODEL_ID to Claude Haiku 4.5 Replace claude-3-5-haiku-20241022-v1:0 (legacy, access-gated) with claude-haiku-4-5-20251001-v1:0 (current, available in account). Verified: model invocable, E2E test passes all 3 tiers (LOW/HIGH/CRITICAL). Standards-Consulted: std.config.model-id-consistency, std.bedrock.verify-model-id-format, std.bedrock.validate-model-before-deploy Standards-Gaps: none Standards-Proposed: none * fix: add .gitignore with lib/ un-ignore for CDK source files The root .gitignore excludes lib/ globally (for compiled JS output in other samples). This project's CDK TypeScript source lives in agentcore/cdk/lib/ and must be tracked. Add project-level .gitignore with negation rules so 'git add' works without -f flag. Standards-Consulted: std.git.no-deployed-state Standards-Gaps: none Standards-Proposed: none * docs: remove sample-level LICENSE, inherit from monorepo root Remove the local MIT-0 LICENSE file from it-incident-response-agent. The sample should inherit the root repo's Apache 2.0 license, consistent with all other samples in 02-use-cases/. * feat: migrate observability to declarative agentcore.json, add Cedar policy steering - Move OTEL/X-Ray env vars to agentcore.json runtimes[].envVars[] - Add instrumentation.enableOtel: true - Add onlineEvalConfigs[] (4 built-in evaluators, 100% sampling) - Add policyEngines[] with Cedar policies (resource is AgentCore::Gateway) - Add policyEngineConfiguration to gateway (LOG_ONLY mode) - Remove ~150 lines of imperative CDK (custom resource, env var overrides) - L3 construct now handles gateway lambda:InvokeFunction automatically - Rename target from 'default' to 'dev' - Fix trigger Lambda runtimeSessionId length (min 33 chars) - Add Cedar policy syntax steering file - Update README with CLI commands for online-eval + policy-engine * chore: remove .kiro/ from git tracking, add to .gitignore * fix: update evaluate.py * refactor: simplify evaluate.py to retrieve online eval results Replace complex on-demand evaluation with a script that queries the online evaluation results log group. The continuous online evaluation (agentcore.json onlineEvalConfigs[]) scores all invocations automatically. Standards-Consulted: std.docs.current-state-only Standards-Gaps: none Standards-Proposed: none * chore: clean up developer-only artifacts and reduce consumer confusion - Remove AGENTS.md from tracking (Kiro AI context, not for consumers) - Reorganize .gitignore with categories, add developer-only file exclusions - Rename docs/online-eval-workaround.md → online-evaluation.md - Trim ARCHITECTURE.md auth deep-dive (link to authentication-guide.md) - Simplify README: collapse manual path, clarify CLI-first section, remove duplicate env-var table, consolidate Configure section * feat: add OTEL span attributes, tool-call hooks, e2e test, and eval reporter - Add ticket.id/priority/requester_id/mode as OTEL span attributes for end-to-end trace correlation via CloudWatch Transaction Search - Add Strands BeforeToolCallEvent/AfterToolCallEvent hooks for per-tool call timing in runtime logs - Add scripts/e2e_test.py with live status polling, log tailing, and post-resolution tool call timeline - Rewrite scripts/evaluate.py to parse online eval results with summary (avg scores by evaluator) and detailed per-trace breakdown * remove: deprecate 02-use-cases/it-incident-response-agent (v1) The v1 sample at 02-use-cases/it-incident-response-agent/ is superseded by 02-use-cases/automation-agents/it-incident-response-agent/, which is an evolved version of the same use case with significant improvements: - CLI-first workflow (agentcore.json + agentcore deploy) vs raw CDK - Zero external prerequisites to deploy (Auth0/Jira optional, not required) - All 6 AgentCore services demonstrated (adds Policy Engine, Guardrails) - Production patterns: DLQ, idempotency, cost routing, graceful degradation - Local dev support (agentcore dev with hot-reload) - L3 CDK constructs instead of L1 CfnResource boilerplate - Comprehensive documentation and design-decisions ADRs The v1 code used raw L1 CfnResource constructs with mandatory Auth0 + Jira dependencies, making it inaccessible for quick-start consumers. All v1 functionality (Jira integration, Auth0 CUSTOM_JWT, Atlassian 3LO, online evaluation) is preserved in the automation-agents version as optional toggles. * style: fix lint and format issues for CI compliance Python (ruff): - Remove unused imports: get_all_mcp_clients, get_streamable_http_mcp_client (main.py), os (jira_oauth_provider.py), time (seeder.py) - Auto-format 8 files to pass ruff format check TypeScript (Prettier): - Auto-format cdk-stack.ts, infra-construct.ts, bin/cdk.ts All CI checks now pass: - ruff check: 0 errors - ruff format --check: 21 files formatted - prettier --check: all files pass - tsc --noEmit: compiles clean - agentcore validate: Valid * chore: gitignore eval doc build artifacts * Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Will Matos <wilmatos@amazon.com> * Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Will Matos <wilmatos@amazon.com> * fix: resolve ruff lint errors in e2e_test.py - F541: Remove extraneous f-prefix on string without placeholders (line 157) - F841: Remove unused variable base_ts (line 270) Standards-Consulted: std.python.ruff-lint-clean Standards-Gaps: none Standards-Proposed: none * fix: additional e2e_test.py improvements * fix: e2e_test.py refinements * fix: code review improvements - error handling, threading, cleanup - Wrap _resolve_ticket DDB call in try/except (non-fatal failure) - Add DEBUG log for silent OTEL ImportError - Remove unused imports in mcp_client/jira.py - Add docstrings to memory/session.py - Move import threading to top-level in e2e_test.py - Replace mutable list stop flag with threading.Event Verified: all Python files parse cleanly, tsc --noEmit passes, agentcore validate passes, CDK tests pass, 50-ticket E2E test 100% pass. * feat: enable Transaction Search observability and tighten IAM scoping - Add OTEL/GenAI observability env vars (AGENT_OBSERVABILITY_ENABLED, message-content capture, application signals) to agentcore.json - Add Transaction Search custom resource Lambda to route X-Ray segments to CloudWatch Logs (aws/spans) for online eval ingestion - Scope trigger Lambda to bedrock-agentcore:InvokeAgentRuntime on the specific runtime ARN (least privilege) - Add resource-based lambda:InvokeFunction permissions for Gateway targets - Make _fail_ticket DDB write non-fatal with exception logging - Misc lint/cleanup in lambdas and e2e_test.py * docs: reflect auto-enabled Transaction Search via custom resource Transaction Search is now provisioned automatically by the CDK stack (transaction_search.py custom resource) when onlineEvalConfigs is set, so manual 'aws application-signals start-monitoring' is no longer required. Update README, online-evaluation.md, and ARCHITECTURE.md accordingly. * refactor: remove redundant L3-provided config, restore Memory resource - Remove redundant XRayTracing IAM statement from RuntimeAdditionalPolicy (L3 RuntimeExecutionRole already grants xray put-trace perms); keep CloudWatch Logs Insights - Remove instrumentation.enableOtel from agentcore.json (OTEL wrapping provided by Dockerfile CMD opentelemetry-instrument for Container build) - Move AGENT_MODEL_ID/FAST_MODEL_ID into agentcore.json runtimes[].envVars[] (declarative, was imperative addPropertyOverride) - Restore Memory resource (ITIncidentAgentMemory, SUMMARIZATION, namespace incidents/{actorId}) so memory code is backed by a provisioned resource instead of a no-op - Enable ACTIVE X-Ray tracing on trigger Lambda for full service-map coverage - Update README/ARCHITECTURE/online-evaluation docs; add 'agentcore add memory' CLI instructions * docs: fix stale references in auth and schema docs - authentication-guide: JIRA_MCP_URL is a hardcoded constant set by CDK, not auto-derived from JIRA_SITE_URL - custom-jwt-auth-upgrade: correct stale function name _get_oauth_token() -> _create_custom_jwt_client() - .llm-context/README: remove reference to non-existent mcp.ts schema file * fix: deploy blockers for Memory namespace and gateway target IAM ordering - Memory SUMMARIZATION namespace requires {sessionId}: incidents/{actorId} -> incidents/{actorId}/{sessionId} (CreateMemory validation failed without it). Retrieval still works via the incidents/{actorId} prefix (prefix matching). - GatewayTargets now explicitly depend on the gateway role DefaultPolicy. The AgentCoreMcp L3 creates the lambda:InvokeFunction policy but does not order targets after it, causing deterministic 'Gateway execution role lacks permission' CREATE_FAILED. Replaces the ineffective resource-based fn.addPermission approach. - README: Getting Started section (CI doc gate), Memory namespace + sessionId note - ARCHITECTURE: corrected Memory namespace note * style: lint fixes (ruff/pylint) with no behavior change - main.py: remove unused imports GATEWAY_URL, MEMORY_ID (ruff F401); they are imported where actually used in mcp_client/memory modules - mcp_client/client.py: remove unnecessary else-after-return (pylint R1705) - mcp_client/client.py, jira.py: scoped 'pylint: disable=missing-kwoa' with justification on @requires_access_token-decorated calls (decorator injects access_token; pylint cannot see the transform) * style: black formatting in lambda handlers (no behavior change) - transaction_search.py: collapse wrapped log line - ticket_event_handler.py: expand ALLOWED_FIELDS set to multi-line, collapse RuntimeError * fix: auto-trigger KB ingestion on deploy by passing DataSourceId to seeder The seeder gates ingestion on 'kb_id and data_source_id', but the CDK only passed KnowledgeBaseId — DataSourceId was never wired through, so start_ingestion_job never ran and the auto-created KB stayed empty until manual ingestion. Capture the data source id on InfraConstruct (knowledgeBaseDataSourceId) and pass DataSourceId to the TriggerSeeder custom resource. README updated: ingestion is now automatic; manual command kept as optional re-index. * fix: validate ticket_id/issue_key in agent entrypoint to avoid uncaught KeyError payload['ticket_id'] was read outside the main try block, so a malformed/direct invoke missing ticket_id (and issue_key) raised an uncaught KeyError that crashed the invoke generator with no structured response. Use payload.get() with an explicit guard that yields a structured Failed result and returns; tighten is_jira_mode to bool(JIRA_MCP_URL). * fix: agent entrypoint robustness Guard model output extraction; empty output raises ValueError so the ticket is marked Failed (requires human processing) rather than resolved with a fallback. Sanitize both title and description through the guardrail. Remove dual logger alias. Avoid unbound agent reference when both initializations fail in prompt mode. Findings #3, #6, #7, #8 * fix: memory cross-session retrieval Use namespace_path (prefix match) instead of namespace (exact match) so prior-session memories are retrieved during enrichment. Finding #4 * fix: atomic change-request write + reason field Use transact_write_items for the dual DynamoDB write so the change request and audit records commit atomically. Add the reason parameter to the tool schema and wire it through, making the RequireReasonForChangeRequest Cedar policy functional. Findings #5, #12 * fix: DynamoDB Decimal serialization in tools Convert DynamoDB Decimal values to native int/float before json.dumps so tool responses serialize correctly. Finding #15 * fix: trigger region + KB ingestion re-run + QueryKb env Pass region_name to boto3 clients in the ticket event trigger. Add commonEnv to QueryKbFn. Bump the seeder Version to 3 so the KB data source ingestion re-runs. Findings #9, #10, #14 * fix: e2e span duration unit Correct the span duration unit conversion in the e2e test. Finding #11 * style: pylint cleanups in e2e_test and evaluate scripts - Drop unused loop variable, specify UTF-8 encoding on open() - Simplify elif-after-return in _score_bar - Add main() docstrings and wrap long lines * style: wrap long lines in agent and lambda modules (C0301) * style: apply ruff format (line-length 120) * chore: rename folder * feat(docs): update docs * chore(usecases) - restructure under workflow * feat(it-incident-agent): stream real-time pipeline stages + evaluations UI + demo - Agent (main.py): emit real SSE stage events at each pipeline phase (guardrail, memory, tools, diagnose, per-tool-call, persist, emit) using agent.stream_async() instead of blocking agent() call - Docs: add Real-Time Progress Streaming section to ARCHITECTURE.md - README: add demo GIF showcasing the full workflow - lambdas/tools: minor cleanup in create_change_request.py - .pylintrc: project lint config * style: add blank line before _stage_event function * chore: update .gitignore for AgentCore CLI and CDK artifacts * feat: add AgentCore CDK infrastructure (DynamoDB, Lambda, Cognito, EventBridge) * feat: implement dual-agent claims processor with memory and MCP Gateway * feat: update Lambda tool handlers with input validation and routing * feat: add one-command deploy/destroy scripts and .env.example * feat: add E2E test suite, Cedar tests, lint script, and unit tests * docs: add architecture, deployment guide, ADRs, and update README * refactor: remove legacy infra/ directory (replaced by agentcore/cdk/) * chore: add gitignore negations for claims-agent CDK lib and Dockerfile * fix: switch test_invoke.py to SigV4 auth (Runtime uses AWS_IAM, not JWT) * docs: regenerate architecture diagrams and fix Runtime auth description * style: fix import sorting and trailing whitespace (ruff auto-fix) * chore: add wilmatos to CONTRIBUTORS.md * style(event-driven-claims-agent): apply ruff format * chore(event-driven-claims-agent): improve lint.sh with verbose output, format check, and tsc * fix(claims-agent): use SigV4 for Runtime invocation, not JWT The Runtime uses IAM (SigV4) auth; CUSTOM_JWT is only for the Gateway. - Trigger Lambda: replace Cognito JWT flow with SigV4 signing - test_e2e.py: switch from Bearer token to SigV4, relax assertions to match actual agent streaming output format - Dockerfile: add non-root user and healthcheck (CKV_DOCKER_2/3) - test_local.py: add URL scheme validation, suppress S310 lint * feat(it-incident-response-agent): production-ready IT incident response agent with streaming and observability (#1724) * feat(usecases): it-incident-response * add jira integration * fix minor memory usage points * docs: add IT incident response agent project docs and assets * config: add AgentCore project configuration and schema context * infra: add CDK project for AgentCore L3 construct deployment * feat: add Strands agent application (runtime, memory, MCP client, model) * feat: add Lambda functions for tools, infra providers, and ticket trigger * feat: add tool schemas, seed data, and knowledge base runbooks * chore: add deployment, evaluation, and ticket utility scripts * docs: comply with use-case README template (add details table and disclaimer) * chore: allow esbuild install script in CDK project * fix: create S3 Vectors bucket+index for KB (CFN does not auto-create) The Bedrock KnowledgeBase CloudFormation resource with type S3_VECTORS requires a pre-existing vector bucket and index. Passing an empty s3VectorsConfiguration fails schema validation. The console's 'quick create' auto-provisions these, but CloudFormation does not. Changes: - Import aws-cdk-lib/aws-s3vectors - Create CfnVectorBucket (named per account+region) - Create CfnIndex (float32, 1024 dims, cosine, no metadata keys) - Wire IndexArn, IndexName, VectorBucketArn into KB storageConfiguration - Grant KB role s3vectors:* actions on the vector index - Add removalPolicy to bucket+index - Add troubleshooting row to README - Deleted the ROLLBACK_COMPLETE stack to unblock next deploy * fix: resolve deploy issues (template envsubst, target name, IndexName removal) - aws-targets.json.template: fix envsubst-incompatible default syntax (${AWS_REGION:-us-west-2} → ${AWS_REGION}), change name 'dev' → 'default' - scripts/deploy.sh: export AWS_REGION with default before envsubst runs - infra-construct.ts: remove IndexName from s3VectorsConfiguration (caused CFN 'oneOf 2 subschemas matched' validation error — only IndexArn + VectorBucketArn are needed for BYO S3 Vectors) - deployed-state.json: updated by successful deploy * docs: update Quickstart to lead with deploy.sh as primary path * chore: stop tracking deployed-state.json (deployment-specific, not shared) * refactor(auth): rename OAUTH_PROVIDER_NAME to GATEWAY_OAUTH_PROVIDER_NAME Scope auth env vars per boundary for clarity: - OAUTH_PROVIDER_NAME -> GATEWAY_OAUTH_PROVIDER_NAME - GATEWAY_AUDIENCE -> GATEWAY_OAUTH_AUDIENCE Code maintains backward-compat fallback to legacy names. CDK injects new names into Runtime env vars at deploy. .env.example and agentcore/.env.local.example updated with boundary labels (Boundary 2, Boundary 3). * docs(auth): add authentication boundary guide New docs/authentication-guide.md explains the 3 auth boundaries: 1. Runtime Inbound (SigV4 vs CUSTOM_JWT) 2. Gateway Outbound (AWS_IAM vs CUSTOM_JWT M2M) 3. Jira Outbound (USER_FEDERATION 3LO) Covers: conceptual overview, env var reference, local dev implications, troubleshooting, and why all 3 patterns exist. * docs: fix local dev ports, CLI commands, and env var references README.md: - Add Port Mapping section (8081=Web UI, 8082=Runtime container) - Add troubleshooting entry for workload access token error - Fix agentcore invoke --dev (invalid) -> agentcore dev prompt - Update config table to use GATEWAY_OAUTH_* var names docs/custom-jwt-auth-upgrade.md: - Update all OAUTH_PROVIDER_NAME -> GATEWAY_OAUTH_PROVIDER_NAME - Update all GATEWAY_AUDIENCE -> GATEWAY_OAUTH_AUDIENCE docs/ARCHITECTURE.md: - Wrap ASCII diagrams in <details> tags for readability * Fix S3 Vectors Knowledge Base schema: remove indexName from s3VectorsConfiguration CloudFormation's AWS::Bedrock::KnowledgeBase type with S3_VECTORS storage has a schema constraint (oneOf) that rejects when both indexArn and indexName are provided. Pass only vectorBucketArn + indexArn to satisfy the schema. The indexName is implicit in the indexArn and Bedrock manages metadata internally during ingestion, so it's not needed in the configuration. Fixes: Properties validation failed - 'only 1 subschema matches out of 2' Verified: Stack now deploys successfully with CREATE_COMPLETE status * feat: migrate online eval to declarative agentcore.json Remove the custom resource workaround for Online Evaluation. The AgentCoreOnlineEvaluationConfig L3 construct (@aws/agentcore-cdk v0.1.0-alpha.34+) now handles dependency ordering automatically. Changes: - Delete lambdas/infra/online_eval_provider.py (custom resource Lambda) - Remove SKIP_ONLINE_EVAL logic from cdk-stack.ts and bin/cdk.ts - Online eval is now purely declarative via agentcore.json onlineEvalConfigs[] - To disable: set onlineEvalConfigs to [] in agentcore.json Standards-Consulted: std.cdk.prefer-declarative Standards-Gaps: none Standards-Proposed: none * fix: align model IDs with available Bedrock models Update all model ID references to use the exact identifiers from `aws bedrock list-foundation-models`: - AGENT_MODEL_ID: us.anthropic.claude-sonnet-4-6 (not -20250929-v1:0) - FAST_MODEL_ID: us.anthropic.claude-3-5-haiku-20241022-v1:0 - JUDGE_MODEL_ID: us.anthropic.claude-sonnet-4-6 The previous IDs (with -20250929-v1:0 suffix) were invalid and caused runtime ValidationException on agent invocation. Standards-Consulted: std.config.model-id-consistency, std.bedrock.verify-model-id-format Standards-Gaps: none Standards-Proposed: std.config.model-id-consistency, std.bedrock.verify-model-id-format, std.bedrock.validate-model-before-deploy * fix: add --target dev to all agentcore CLI commands This project uses a named target 'dev' in aws-targets.json (not the default target). All CLI invocations must explicitly pass --target dev. Standards-Consulted: std.deploy.target-dev Standards-Gaps: none Standards-Proposed: std.deploy.target-dev * docs: overhaul documentation to describe current state only - Remove SKIP_ONLINE_EVAL references throughout - Fix model IDs in all documentation - Remove .kiro references from public docs - Merge duplicate Online Eval sections in README - Fix GUARDRAIL_ID default (auto-creates, not skips) - Fix target name in troubleshooting (dev, not default) - Add --target dev to all documented deploy commands - Add Declarative vs Imperative section to ARCHITECTURE.md - Remove stale development process docs (8 root-level .md files) - Pad all README tables for aligned vertical bars Standards-Consulted: std.docs.current-state-only, std.deploy.target-dev, std.config.model-id-consistency Standards-Gaps: none Standards-Proposed: std.docs.current-state-only * chore: update agentcore config and CDK dependencies - agentcore.json: add onlineEvalConfigs, policyEngines, gateway config - aws-targets.json.template: minor format fix - CDK packages: update @aws/agentcore-cdk dependency range Standards-Consulted: std.cdk.prefer-declarative, std.deploy.target-dev Standards-Gaps: none Standards-Proposed: none * feat: improve agent resilience and MCP client handling - main.py: add graceful degradation when MCP tools unavailable, safe fallback to LLM-only mode on tool initialization failure - mcp_client/client.py: add get_all_mcp_clients_safe() with error collection instead of hard failure - trigger: minor fix - show_ticket.sh: minor fix Standards-Consulted: std.agentcore.mcp-sigv4-auth Standards-Gaps: none Standards-Proposed: none * feat: add end-to-end test script scripts/test-e2e.sh publishes a ticket to SNS, polls DynamoDB for resolution (10s intervals, 120s timeout), and asserts status=Resolved with a non-empty resolution_comment. Exits 0 on pass, 1 on fail. Usage: ./scripts/test-e2e.sh # sample ticket ./scripts/test-e2e.sh /path/to/ticket.json # custom ticket Standards-Consulted: std.deploy.target-dev Standards-Gaps: none Standards-Proposed: none * feat: upgrade FAST_MODEL_ID to Claude Haiku 4.5 Replace claude-3-5-haiku-20241022-v1:0 (legacy, access-gated) with claude-haiku-4-5-20251001-v1:0 (current, available in account). Verified: model invocable, E2E test passes all 3 tiers (LOW/HIGH/CRITICAL). Standards-Consulted: std.config.model-id-consistency, std.bedrock.verify-model-id-format, std.bedrock.validate-model-before-deploy Standards-Gaps: none Standards-Proposed: none * fix: add .gitignore with lib/ un-ignore for CDK source files The root .gitignore excludes lib/ globally (for compiled JS output in other samples). This project's CDK TypeScript source lives in agentcore/cdk/lib/ and must be tracked. Add project-level .gitignore with negation rules so 'git add' works without -f flag. Standards-Consulted: std.git.no-deployed-state Standards-Gaps: none Standards-Proposed: none * docs: remove sample-level LICENSE, inherit from monorepo root Remove the local MIT-0 LICENSE file from it-incident-response-agent. The sample should inherit the root repo's Apache 2.0 license, consistent with all other samples in 02-use-cases/. * feat: migrate observability to declarative agentcore.json, add Cedar policy steering - Move OTEL/X-Ray env vars to agentcore.json runtimes[].envVars[] - Add instrumentation.enableOtel: true - Add onlineEvalConfigs[] (4 built-in evaluators, 100% sampling) - Add policyEngines[] with Cedar policies (resource is AgentCore::Gateway) - Add policyEngineConfiguration to gateway (LOG_ONLY mode) - Remove ~150 lines of imperative CDK (custom resource, env var overrides) - L3 construct now handles gateway lambda:InvokeFunction automatically - Rename target from 'default' to 'dev' - Fix trigger Lambda runtimeSessionId length (min 33 chars) - Add Cedar policy syntax steering file - Update README with CLI commands for online-eval + policy-engine * chore: remove .kiro/ from git tracking, add to .gitignore * fix: update evaluate.py * refactor: simplify evaluate.py to retrieve online eval results Replace complex on-demand evaluation with a script that queries the online evaluation results log group. The continuous online evaluation (agentcore.json onlineEvalConfigs[]) scores all invocations automatically. Standards-Consulted: std.docs.current-state-only Standards-Gaps: none Standards-Proposed: none * chore: clean up developer-only artifacts and reduce consumer confusion - Remove AGENTS.md from tracking (Kiro AI context, not for consumers) - Reorganize .gitignore with categories, add developer-only file exclusions - Rename docs/online-eval-workaround.md → online-evaluation.md - Trim ARCHITECTURE.md auth deep-dive (link to authentication-guide.md) - Simplify README: collapse manual path, clarify CLI-first section, remove duplicate env-var table, consolidate Configure section * feat: add OTEL span attributes, tool-call hooks, e2e test, and eval reporter - Add ticket.id/priority/requester_id/mode as OTEL span attributes for end-to-end trace correlation via CloudWatch Transaction Search - Add Strands BeforeToolCallEvent/AfterToolCallEvent hooks for per-tool call timing in runtime logs - Add scripts/e2e_test.py with live status polling, log tailing, and post-resolution tool call timeline - Rewrite scripts/evaluate.py to parse online eval results with summary (avg scores by evaluator) and detailed per-trace breakdown * remove: deprecate 02-use-cases/it-incident-response-agent (v1) The v1 sample at 02-use-cases/it-incident-response-agent/ is superseded by 02-use-cases/automation-agents/it-incident-response-agent/, which is an evolved version of the same use case with significant improvements: - CLI-first workflow (agentcore.json + agentcore deploy) vs raw CDK - Zero external prerequisites to deploy (Auth0/Jira optional, not required) - All 6 AgentCore services demonstrated (adds Policy Engine, Guardrails) - Production patterns: DLQ, idempotency, cost routing, graceful degradation - Local dev support (agentcore dev with hot-reload) - L3 CDK constructs instead of L1 CfnResource boilerplate - Comprehensive documentation and design-decisions ADRs The v1 code used raw L1 CfnResource constructs with mandatory Auth0 + Jira dependencies, making it inaccessible for quick-start consumers. All v1 functionality (Jira integration, Auth0 CUSTOM_JWT, Atlassian 3LO, online evaluation) is preserved in the automation-agents version as optional toggles. * style: fix lint and format issues for CI compliance Python (ruff): - Remove unused imports: get_all_mcp_clients, get_streamable_http_mcp_client (main.py), os (jira_oauth_provider.py), time (seeder.py) - Auto-format 8 files to pass ruff format check TypeScript (Prettier): - Auto-format cdk-stack.ts, infra-construct.ts, bin/cdk.ts All CI checks now pass: - ruff check: 0 errors - ruff format --check: 21 files formatted - prettier --check: all files pass - tsc --noEmit: compiles clean - agentcore validate: Valid * chore: gitignore eval doc build artifacts * Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Will Matos <wilmatos@amazon.com> * Potential fix for pull request finding 'CodeQL / Clear-text logging of sensitive information' Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Signed-off-by: Will Matos <wilmatos@amazon.com> * fix: resolve ruff lint errors in e2e_test.py - F541: Remove extraneous f-prefix on string without placeholders (line 157) - F841: Remove unused variable base_ts (line 270) Standards-Consulted: std.python.ruff-lint-clean Standards-Gaps: none Standards-Proposed: none * fix: additional e2e_test.py improvements * fix: e2e_test.py refinements * fix: code review improvements - error handling, threading, cleanup - Wrap _resolve_ticket DDB call in try/except (non-fatal failure) - Add DEBUG log for silent OTEL ImportError - Remove unused imports in mcp_client/jira.py - Add docstrings to memory/session.py - Move import threading to top-level in e2e_test.py - Replace mutable list stop flag with threading.Event Verified: all Python files parse cleanly, tsc --noEmit passes, agentcore validate passes, CDK tests pass, 50-ticket E2E test 100% pass. * feat: enable Transaction Search observability and tighten IAM scoping - Add OTEL/GenAI observability env vars (AGENT_OBSERVABILITY_ENABLED, message-content capture, application signals) to agentcore.json - Add Transaction Search custom resource Lambda to route X-Ray segments to CloudWatch Logs (aws/spans) for online eval ingestion - Scope trigger Lambda to bedrock-agentcore:InvokeAgentRuntime on the specific runtime ARN (least privilege) - Add resource-based lambda:InvokeFunction permissions for Gateway targets - Make _fail_ticket DDB write non-fatal with exception logging - Misc lint/cleanup in lambdas and e2e_test.py * docs: reflect auto-enabled Transaction Search via custom resource Transaction Search is now provisioned automatically by the CDK stack (transaction_search.py custom resource) when onlineEvalConfigs is set, so manual 'aws application-signals start-monitoring' is no longer required. Update README, online-evaluation.md, and ARCHITECTURE.md accordingly. * refactor: remove redundant L3-provided config, restore Memory resource - Remove redundant XRayTracing IAM statement from RuntimeAdditionalPolicy (L3 RuntimeExecutionRole already grants xray put-trace perms); keep CloudWatch Logs Insights - Remove instrumentation.enableOtel from agentcore.json (OTEL wrapping provided by Dockerfile CMD opentelemetry-instrument for Container build) - Move AGENT_MODEL_ID/FAST_MODEL_ID into agentcore.json runtimes[].envVars[] (declarative, was imperative addPropertyOverride) - Restore Memory resource (ITIncidentAgentMemory, SUMMARIZATION, namespace incidents/{actorId}) so memory code is backed by a provisioned resource instead of a no-op - Enable ACTIVE X-Ray tracing on trigger Lambda for full service-map coverage - Update README/ARCHITECTURE/online-evaluation docs; add 'agentcore add memory' CLI instructions * docs: fix stale references in auth and schema docs - authentication-guide: JIRA_MCP_URL is a hardcoded constant set by CDK, not auto-derived from JIRA_SITE_URL - custom-jwt-auth-upgrade: correct stale function name _get_oauth_token() -> _create_custom_jwt_client() - .llm-context/README: remove reference to non-existent mcp.ts schema file * fix: deploy blockers for Memory namespace and gateway target IAM ordering - Memory SUMMARIZATION namespace requires {sessionId}: incidents/{actorId} -> incidents/{actorId}/{sessionId} (CreateMemory validation failed without it). Retrieval still works via the incidents/{actorId} prefix (prefix matching). - GatewayTargets now explicitly depend on the gateway role DefaultPolicy. The AgentCoreMcp L3 creates the lambda:InvokeFunction policy but does not order targets after it, causing deterministic 'Gateway execution role lacks permission' CREATE_FAILED. Replaces the ineffective resource-based fn.addPermission approach. - README: Getting Started section (CI doc gate), Memory namespace + sessionId note - ARCHITECTURE: corrected Memory namespace note * style: lint fixes (ruff/pylint) with no behavior change - main.py: remove unused imports GATEWAY_URL, MEMORY_ID (ruff F401); they are imported where actually used in mcp_client/memory modules - mcp_client/client.py: remove unnecessary else-after-return (pylint R1705) - mcp_client/client.py, jira.py: scoped 'pylint: disable=missing-kwoa' with justification on @requires_access_token-decorated calls (decorator injects access_token; pylint cannot see the transform) * style: black formatting in lambda handlers (no behavior change) - transaction_search.py: collapse wrapped log line - ticket_event_handler.py: expand ALLOWED_FIELDS set to multi-line, collapse RuntimeError * fix: auto-trigger KB ingestion on deploy by passing DataSourceId to seeder The seeder gates ingestion on 'kb_id and data_source_id', but the CDK only passed KnowledgeBaseId — DataSourceId was never wired through, so start_ingestion_job never ran and the auto-created KB stayed empty until manual ingestion. Capture the data source id on InfraConstruct (knowledgeBaseDataSourceId) and pass DataSourceId to the TriggerSeeder custom resource. README updated: ingestion is now automatic; manual command kept as optional re-index. * fix: validate ticket_id/issue_key in agent entrypoint to avoid uncaught KeyError payload['ticket_id'] was read outside the main try block, so a malformed/direct invoke missing ticket_id (and issue_key) raised an uncaught KeyError that crashed the invoke generator with no structured response. Use payload.get() with an explicit guard that yields a structured Failed result and returns; tighten is_jira_mode to bool(JIRA_MCP_URL). * fix: agent entrypoint robustness Guard model output extraction; empty output raises ValueError so the ticket is marked Failed (requires human processing) rather than resolved with a fallback. Sanitize both title and description through the guardrail. Remove dual logger alias. Avoid unbound agent reference when both initializations fail in prompt mode. Findings #3, #6, #7, #8 * fix: memory cross-session retrieval Use namespace_path (prefix match) instead of namespace (exact match) so prior-session memories are retrieved during enrichment. Finding #4 * fix: atomic change-request write + reason field Use transact_write_items for the dual DynamoDB write so the change request and audit records commit atomically. Add the reason parameter to the tool schema and wire it through, making the RequireReasonForChangeRequest Cedar policy functional. Findings #5, #12 * fix: DynamoDB Decimal serialization in tools Convert DynamoDB Decimal values to native int/float before json.dumps so tool responses serialize correctly. Finding #15 * fix: trigger region + KB ingestion re-run + QueryKb env Pass region_name to boto3 clients in the ticket event trigger. Add commonEnv to QueryKbFn. Bump the seeder Version to 3 so the KB data source ingestion re-runs. Findings #9, #10, #14 * fix: e2e span duration unit Correct the span duration unit conversion in the e2e test. Finding #11 * style: pylint cleanups in e2e_test and evaluate scripts - Drop unused loop variable, specify UTF-8 encoding on open() - Simplify elif-after-return in _score_bar - Add main() docstrings and wrap long lines * style: wrap long lines in agent and lambda modules (C0301) * style: apply ruff format (line-length 120) * chore: rename folder * feat(docs): update docs * chore(usecases) - restructure under workflow * feat(it-incident-agent): stream real-time pipeline stages + evaluations UI + demo - Agent (main.py): emit real SSE stage events at each pipeline phase (guardrail, memory, tools, diagnose, per-tool-call, persist, emit) using agent.stream_async() instead of blocking agent() call - Docs: add Real-Time Progress Streaming section to ARCHITECTURE.md - README: add demo GIF showcasing the full workflow - lambdas/tools: minor cleanup in create_change_request.py - .pylintrc: project lint config * style: add blank line before _stage_event function * chore: update .gitignore for AgentCore CLI and CDK artifacts * feat: add AgentCore CDK infrastructure (DynamoDB, Lambda, Cognito, EventBridge) * feat: implement dual-agent claims processor with memory and MCP Gateway * feat: update Lambda tool handlers with input validation and routing * feat: add one-command deploy/destroy scripts and .env.example * feat: add E2E test suite, Cedar tests, lint script, and unit tests * docs: add architecture, deployment guide, ADRs, and update README * refactor: remove legacy infra/ directory (replaced by agentcore/cdk/) * chore: add gitignore negations for claims-agent CDK lib and Dockerfile * fix: switch test_invoke.py to SigV4 auth (Runtime uses AWS_IAM, not JWT) * docs: regenerate architecture diagrams and fix Runtime auth description * style: fix import sorting and trailing whitespace (ruff auto-fix) * chore: add wilmatos to CONTRIBUTORS.md * style(event-driven-claims-agent): apply ruff format * chore(event-driven-claims-agent): improve lint.sh with verbose output, format check, and tsc * fix(claims-agent): use SigV4 for Runtime invocation, not JWT The Runtime uses IAM (SigV4) auth; CUSTOM_JWT is only for the Gateway. - Trigger Lambda: replace Cognito JWT flow with SigV4 signing - test_e2e.py: switch from Bearer token to SigV4, relax assertions to match actual agent streaming output format - Dockerfile: add non-root user and healthcheck (CKV_DOCKER_2/3) - test_local.py: add URL scheme validation, suppress S310 lint --------- Signed-off-by: Will Matos <wilmatos@amazon.com> Signed-off-by: Akarsha Sehwag <akshseh@amazon.de> Co-authored-by: Akarsha Sehwag <akshseh@amazon.de> Co-authored-by: Akarsha Sehwag <akarsha15010@iiitd.ac.in> Co-authored-by: Will Matos <wmatosjr@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> * Harness GA Samples — AWS Skills, S3 Filesystem, Step Functions, Builder Agent (#1688) * Add Harness GA samples: AWS Skills, S3 filesystem, Step Functions, builder agent Four new samples under 01-features/01-harness for the Harness GA launch: - 01-advanced-examples/08-aws-skills: enable native AWS Skills from the AWS Agent Toolkit via the awsSkills source (all / glob / specific / mixed modes) - 01-advanced-examples/09-s3-filesystem: mount an S3 Files access point as the agent filesystem; includes s3_knowledge_base.py — a persistent LLM-wiki knowledge base (ingest / query / lint) on the S3 mount - 01-advanced-examples/10-stepfunctions-orchestration: a Step Functions STANDARD state machine that drives the harness lifecycle (create -> poll READY -> invoke -> delete) via a Lambda task worker - 02-use-cases/03-aws-builder-agent: harness + AWS Skills compose an AWS engineering agent that designs and scaffolds a serverless app All samples use the GA boto3 SDK shapes (create_harness/invoke_harness) with no internal endpoints or configuration. Updated the harness README index. * Rename s3_knowledge_base.py to s3_llm_wiki.py to avoid Bedrock Knowledge Bases confusion The LLM-wiki sample is a self-maintained markdown wiki on the agent's filesystem, unrelated to the Amazon Bedrock Knowledge Bases feature. Rename the file and scrub 'knowledge base' wording (mount default /mnt/wiki, pages/ subdir) across the script and READMEs to prevent customer confusion. * Fix S3 filesystem + Step Functions samples after end-to-end testing Verified the samples against the live GA API and fixed real bugs found: S3 filesystem (s3_filesystem.py, s3_llm_wiki.py): - S3 Files mounts REQUIRE VPC network mode — add networkConfiguration (networkMode=VPC + subnets + security groups) to create_harness; add required --subnet-ids/--security-group-ids CLI args. - Execution role needs s3files permissions (ListMountTargets/Get*/ClientMount/ ClientWrite/ClientRootAccess), not plain s3:* — correct the attached policy. - README: document VPC + mount-target prerequisites and the new args. Step Functions (stepfunctions_orchestration.py): - Lambda role also needs *AgentRuntime* actions (CreateHarness provisions an underlying AgentRuntime) — without them CreateHarness returns AccessDenied. - CheckStatus Choice now matches CREATE_FAILED/UPDATE_FAILED so a failed creation fails fast instead of looping on the WaitForReady default forever. * Rework Step Functions sample to native integration; fix S3 Files IAM/VPC guidance Step Functions: replace the Lambda task-worker approach with the native arn:aws:states:::bedrockagentcore:invokeHarness service integration — a single Task state, no Lambda, no glue. The state machine's own role gets bedrock-agentcore:InvokeHarness; output is Converse-shaped (Output.Message.Content[].Text). Rewrote the README accordingly. S3 filesystem: scope the execution-role IAM to what the runtime actually needs — s3files:GetAccessPoint (unscoped, validated at harness create time) plus s3files:ClientMount/ClientWrite (conditioned on the access point). Document that S3 Files mounts require VPC network mode with private subnets that have egress (route to a NAT gateway); public subnets do not connect. Same IAM fix applied to the s3_llm_wiki.py sample. * Remove Step Functions sample; renumber to avoid collision with merged samples Upstream main now occupies advanced-examples 01-12 (incl. 06-async-step-function, 08-gemini-model-provider, 09-openai-model-provider). Renumber our two samples to free slots and drop the Step Functions sample (upstream added its own): - delete 10-stepfunctions-orchestration - 08-aws-skills -> 13-aws-skills - 09-s3-filesystem -> 14-s3-filesystem Updated all cross-references (harness index README, builder-agent note). * docs: fix evaluations next step link (#1679) * Add Weather Agent use case with harness, gateway, guardrails, evaluation and observability (#1648) * Add Weather Agent use case with harness, gateway, guardrails, evaluations, and observability * fix: resolve lint errors and security finding (unused imports, f-strings, bind to localhost) * fix: address PR feedback (README clarifications, region detection, graceful eval error, trace display) * feat: add Skills (xlsx report generation) and Optimization (system prompt recommendations) * feat: add Skills (xlsx report generation) and Optimization (system prompt recommendations) * fix: address PR feedback (README clarifications, region detection, graceful eval error, trace display) * Agentcore optimization nys (#1722) * Add failure insights sample (insights.py) and update README - Add insights.py: runs FailureAnalysis, UserIntent, and ExecutionSummary batch insight jobs on the HR Assistant agent. Supports --generate-traces to send curated failure-mode sessions, --online to create a recurring daily OnlineEvaluationConfig, and --insight to select individual insight types. Uses both aws/spans and the runtime log group as data sources. - Update README with a full Failure Insights section covering all three insight types, data source requirements, CLI examples, and how to chain insights into a system prompt recommendation. * sample for agentcore insights feature with SDK scripts and CLI examples * agent loops image * move CLI insights step to after deploy and baseline eval in optimization workflow * remove step 0 from CLI examples * add insights.py description in How It Works section * adding docs links to readme * rename failure insights to insights throughout * fix pylint and ruff issues in insights.py - Add encoding="utf-8" to file read/write calls - Wrap long lines to stay within 100-char limit - Add pylint disable comments for intentional broad-exception-caught - Rename loop variable to avoid module-scope naming false positive - Remove f-string prefix from string literals without placeholders (ruff fix) * remove generated state and config files * remove TEST_LOG.md from registry * scope aws-targets gitignore to exclude gateway config files * clearing outputs from NBs * fix ruff/pylint line-length conflict in optimize folder * update repository structure in readme * updating main readme * replace account numbers and resource IDs with placeholders in optimization notebook * Amazon Bedrock AgentCore Gateway websearch samples and usecases (#1721) * Add AgentCore Web Search Tool samples and workshop content - 01-features: new 03-web-search folder with setup, raw MCP, Strands, and LangChain samples; updated requirements.txt with pinned versions - 06-workshops: new 03-Agent-Core-web-search workshop with 6 notebooks covering gateway setup, Strands agent, LangChain agent, CVE scanner, earnings brief, and iterative research pattern - 06-workshops/05-AgentCore-tools/README.md: added Web Search Tool section * feat: add deep-research-agent with auto-provisioning and search privacy notices - Add deep-research-agent use case with iterative Plan/Search/Reflect/Synthesize loop - Add gateway_setup.py with auto-detect/prompt/provision flow (no hard prerequisites) - Add search privacy callout to all 03-web-search README files - Fix model ID default to use cross-region inference profile - Add user-friendly error handling for auth failures * Update finance budget assistant for Claude Haiku 4.5 (#1742) - Update BUDGET_SYSTEM_PROMPT in lab1: the previous prompt broke the structured output instructions with Claude Haiku 4.5 - Remove outdated note about enabling model access for Claude 3.7 Sonnet - Update references from Anthropic Claude 3.7 Sonnet to Claude Haiku 4.5 in lab1 and README * Add skip-extraction sample and rename 08-redrive to 08-manage-extraction (#1746) Adds a runnable sample demonstrating extractionMode=SKIP on CreateEvent, which stores events in short-term memory without triggering long-term extraction. Renames the folder to 08-manage-extraction to cover both skip and redrive as extraction lifecycle controls. Co-authored-by: Gal Goldman <galgold@amazon.com> * feat(memory): add multi-region-replication example (#1747) * feat(memory): add multi-region-replication example * feat(memory): update func * chore: ruff formatting * feat(use-cases): add multi-ISV orchestration sample (Salesforce + SAP) (#1640) * feat(use-cases): add multi-ISV orchestration sample — Salesforce + SAP Add a standalone use case under 02-use-cases/multi-isv-orchestration/ demonstrating how to connect Salesforce Lightning Platform and AWS for SAP MCP Server to a single AgentCore Gateway, enabling cross-system AI agent workflows through one unified MCP endpoint. Three Jupyter notebooks walk through: - 01: Salesforce as integration target (CustomOauth2, 43 tools) - 02: SAP MCP Server as MCP target (9 tools, read-only default) - 03: Cross-ISV queries (Customer 360, pipeline reconciliation) Includes gateway_mcp_client.py utility, architecture diagrams, and documented workarounds (Content-Type, domainName, org hibernation). Originally proposed under 01-tutorials/02-AgentCore-gateway/ in #1487; relocated to 02-use-cases/ to fit the new repo structure where 01-features/ is CLI-only and end-to-end samples live under 02-use-cases/. * security(multi-isv): scope Gateway IAM role and harden notebook inputs Address threat-model review feedback on the multi-ISV orchestration sample: - Scope the Gateway execution-role policy: split the single Resource:"*" statement into four scoped statements (bedrock:InvokeModel limited to the Claude model/inference-profile ARNs, secretsmanager:GetSecretValue limited to the bedrock-agentcore-* secret prefix, iam:PassRole limited to the role itself with a PassedToService condition); remove the unused s3:GetObject. - Stop printing the Cognito client secret in the NB01 summary; show the describe-user-pool-client retrieval command instead. - Validate SF_DOMAIN against a strict [A-Za-z0-9-]+ pattern to prevent redirecting tool calls to an attacker-controlled host. - Update the README Disclaimer to reflect the scoped IAM policy. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(multi-isv): add sample to workflow-automation category README List multi-isv-orchestration in the 02-workflow-automation-agents samples table after relocating the folder into that category. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * `feat(04-coding-agents): add sample 05 — autonomous coding agent with durable orchestration` (#1725) * feat: add sample 05 — autonomous coding agent with durable orchestration Event-driven headless coding backend on AgentCore Runtime with: - Lambda Durable Function orchestrator (zero-cost suspension) - 4 specialized runtimes (coding agent, sandbox, Swift sandbox, evaluator) - Cedar policy enforcement at sandbox layer - AgentCore Memory for cross-ticket learning - Evaluator agent for read-only code review - CDK deployment (8 stacks) * docs: note that sandbox examples cover Python and Swift but are extendable to other frameworks * fix: resolve ruff lint violations (E741, E401, F541) across four files - Rename ambiguous variable l to lesson in list comprehensions (shared/memory.py, orchestrator/handler.py) - Split multi-import into separate statements (sandbox/app.py) - Remove unnecessary f-string prefix (cdk/stacks/storage_stack.py) - Add property-based tests verifying lint compliance and behavior preservation * fix: suppress 8 false-positive ASH security findings with inline annotations - Add # nosec B108 to intentional /tmp usage in isolated containers/microVMs - Add # nosec B602 to sandboxed subprocess executor (sandbox/app.py) - Add # nosec B108 to test files (assertions and fixtures, not real /tmp usage) - Add #checkov:skip=CKV_DOCKER_3 to Dockerfile.swift (entrypoint.sh handles su) - Each annotation includes justification for audit trail * chore: remove AgentCore diagram icon PNGs from claims agent docs * feat: refactor agent core — inline MCP client, add routing module, remove legacy modules - Rewrite main.py: inline @requires_access_token MCP client builder, structured output tools, confidence-based routing via routing.py - Add routing.py: extracted pure routing logic (resolve_decision, resolve_routing, decide_action) with safe fallback defaults - Update config.py: L3 construct auto-generated env var support, memory retrieval tuning params, credential provider config - Update memory/session.py: configurable retrieval top_k and relevance - Update Dockerfile: base image, uv sync steps - Update pyproject.toml/requirements.txt/uv.lock: dependency refresh - Remove mcp_client/ module: replaced by inline client in main.py - Remove model/ module: load_model() now inline in main.py - Remove parsing.py: regex parsing replaced by structured output tools * feat: update CDK infra and agentcore.json for Identity-managed auth - agentcore.json: add Cognito OAuth credential provider, OnlineEval evaluator config, SEMANTIC + SUMMARIZATION memory strategies - cdk-stack.ts: patch Lambda ARNs into gateway targets, wire CUSTOM_JWT authorizer from Cognito discovery URL, add gateway target dependency ordering fix, suppress mis-parsed target outputs - infra-construct.ts: add DynamoDB GSIs (status, claim_id), S3 bucket with EventBridge notifications, SNS topic, 6 Lambda tool functions + trigger, EventBridge rule for S3 PutObject - cdk.ts: updated stack instantiation with spec/mcpSpec/credentials - package.json/package-lock.json: CDK dependency updates * feat: update Lambda handlers and trigger for simplified routing - trigger/handler.py: SigV4-signed HTTPS invocation to Runtime, email parsing with claimant_email extraction, SSE response buffering - list_pending_claims/handler.py: use GSI query instead of table scan - notification/handler.py: updated response format, error handling - resolve_claim/handler.py: write resolution to both Claims + Reviews tables * feat: add deploy, teardown, auth, and observability scripts * test: add unit tests for routing, structured output, Lambda handlers, trigger * docs: update architecture, decisions, deployment, and configuration docs - AGENTS.md: updated AI assistant context for current architecture - README.md: updated quick start, project structure, commands - .env.example: updated template for Identity-managed auth - .gitignore: remove docs/decisions/ exclusion (publish ADRs) - docs/ARCHITECTURE.md: updated system design, component descriptions - docs/CONFIGURATION.md: updated config reference - docs/README.md: updated index and prerequisites - docs/deployment.md: updated deploy/verify/teardown steps - docs/tutorial.md: updated guided walkthrough - docs/decisions/0004: rewritten as Hybrid Auth (SigV4 + Cognito M2M) - docs/decisions/0010: rewritten + renamed (Identity token vault) - docs/decisions/0011-0012: now tracked (externalized config, GSI) - docs/decisions/README.md: updated index with correct titles * claims-agent: fire-and-forget trigger, resilient prompts, e2e timing - Trigger Lambda: fire-and-forget invocation (read first 5 lines only, don't buffer full SSE stream). Timeout bumped to 65s for cold starts. - Trigger Lambda timeout in CDK: 60s → 90s to cover Runtime cold start. - Processor prompt: graceful handling when lookup_policy fails, guard against tool hallucination and fabricated policy details. - E2E tests: add per-test timing, increase async wait to 90s. - ARCHITECTURE.md: document fire-and-forget pattern. - Add scripts/analyze_traces.py for OTEL trace analysis. * feat(claims-agent): add cost-based model routing for Validation Agent Route the Validation Agent (Phase 2) to Haiku via FAST_MODEL_ID, saving ~80% cost and 3-8s latency per invocation. The validator performs classification only (no tool use), making it an ideal candidate for a smaller model. Changes: - Add FAST_MODEL_ID env var to config.py, agentcore.json, .env.example - Update load_model() to accept fast=True for cost routing - Wire get_validator() to use the fast model - Add ADR-0013 documenting the decision - Update AGENTS.md, ARCHITECTURE.md, CONFIGURATION.md * claims-agent: cost routing (FAST_MODEL_ID) + deterministic Phase 3 Performance optimizations: - Add FAST_MODEL_ID (Haiku) for Phase 2 Validation Agent — classification task doesn't need Sonnet. Saves 3-8s and ~80% cost per invocation. - Replace Phase 3 LLM call with direct MCPClient.call_tool_async() calls. Routing is deterministic after Phase 2; no LLM needed. Saves 6-16s. - Combined: pipeline goes from 3 Sonnet calls to 1 Sonnet + 1 Haiku + 0. Measured: 65s (deployed old) → 28s (local new) = 56% reduction. Code changes: - config.py: add FAST_MODEL_ID env var - main.py: load_model(fast=True) for validator, _call_tool() helper for direct MCP calls, deterministic Phase 3 with non-fatal error handling - agentcore.json: add FAST_MODEL_ID to runtime envVars - .env.example: document FAST_MODEL_ID Documentation: - AGENTS.md: updated description, architecture diagram, invariant #8 - ARCHITECTURE.md: Phase 3 deterministic section, model routing line - CONFIGURATION.md: FAST_MODEL_ID in both config tables - deployment.md: fix --no-browser → --logs, port 3000 → 8080, Phase 3 output - README.md: updated Phase 3 expected output - ADR-0013: cost-based model routing decision - ADR-0014: deterministic Phase 3 decision - Skill ref: mcp-client-patterns.md (correct call_tool_async API) * chore(claims-agent): sanitize agentcore.json and improve E2E tests/docs - Replace env-specific Cognito discovery URL with PLACEHOLDER_USER_POOL_ID - Add gateway exceptionLevel: NONE - test_e2e.py: evidence-based assertions + --verbose flag - deployment.md: add troubleshooting and config reference - Add fix_credential_region.sh helper - gitignore local backup and perf/design artifacts * chore(claims-agent): placeholder the region in agentcore.json discovery URLs Replace hardcoded us-west-2 with PLACEHOLDER_REGION in both the credentials and gateway CUSTOM_JWT discovery URLs. Both values are overridden at deploy (agentcore add credential / CDK authorizer patch), so this keeps the committed config free of environment-specific region info. * docs(claims-agent): refresh architecture diagram, fix ADRs, drop demo video - Regenerate architecture.png (landscape high-level diagram) + commit reproducible source docs/diagrams/architecture.py and AgentCore icons - Reference architecture.png from README.md and docs/ARCHITECTURE.md - Remove stale/duplicate ADR 0010-unsafe-unwrap.md (superseded by 0010-identity-token-vault-for-secrets.md; pattern not in code) - Remove 6MB demo.mp4; README now embeds demo.gif (to be added) * docs(claims-agent): add demo.gif and embed it in README * fix(claims-agent): remove f-string prefix from strings without placeholders (F541) * fix: apply ruff format to 5 Python files (CI lint fix) --------- Signed-off-by: Will Matos <wilmatos@amazon.com> Signed-off-by: Akarsha Sehwag <akshseh@amazon.de> Co-authored-by: Akarsha Sehwag <akshseh@amazon.de> Co-authored-by: Akarsha Sehwag <akarsha15010@iiitd.ac.in> Co-authored-by: Will Matos <wmatosjr@users.noreply.github.com> Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> Co-authored-by: Ed Fraga <39071108+edfragas@users.noreply.github.com> Co-authored-by: 吴杨帆 <39647285+wyf027@users.noreply.github.com> Co-authored-by: JobRamos <33988720+JobRamos@users.noreply.github.com> Co-authored-by: Bharathi Srinivasan <bhrsrini@amazon.com> Co-authored-by: Naga Gaddamu <zigeesha@hotmail.com> Co-authored-by: philgut-aws <philgut@amazon.de> Co-authored-by: gel-work <171434940+gel-work@users.norepl…
1 parent bde5786 commit 69fb6dd

63 files changed

Lines changed: 4306 additions & 1112 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,3 +312,8 @@ plan/
312312
01-features/03-connect-your-agent-to-anything/02-browser/TEST_REPORT_CARD.md
313313
02-use-cases/use-case-assessment.md
314314
**/lambda_config.json
315+
02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/scripts/perf_baseline_results.json
316+
02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/scripts/perf_baseline_results.md
317+
02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/scripts/perf_baseline.py
318+
02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/docs/DESIGN_SYSTEM.md
319+
02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/agentcore/agentcore.json.deployed.bak
Lines changed: 46 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,51 @@
1-
# Event-Driven Claims Agent — Local Development Environment
1+
# Event-Driven Claims Agent — Configuration
22
#
3-
# Copy this file to .env and fill in values from your deployed stack:
4-
# aws cloudformation describe-stacks --stack-name AgentCore-ClaimsAgent-dev --query 'Stacks[0].Outputs' --region us-west-2 --output table
5-
#
6-
# Then run: agentcore dev --no-browser
3+
# Copy to .env and fill in values. The deploy script reads these.
4+
# Run ./scripts/setup_cognito.sh to auto-provision Cognito and fill Gateway values.
5+
6+
# ─── AWS Account & Region
7+
AWS_REGION=us-west-2
8+
# CDK_DEFAULT_ACCOUNT is auto-detected from your AWS credentials if not set here.
79

8-
# MCP Gateway connection (from CloudFormation outputs)
9-
AGENTCORE_GATEWAY_URL=https://YOUR_GATEWAY_ID.gateway.bedrock-agentcore.us-west-2.amazonaws.com/mcp
10-
AGENTCORE_GATEWAY_TOKEN_ENDPOINT=https://claims-agent-YOUR_ACCOUNT_ID.auth.us-west-2.amazoncognito.com/oauth2/token
10+
# ─── MCP Gateway Auth (Cognito M2M)
11+
# These configure how the Runtime authenticates to the MCP Gateway.
12+
# Run: ./scripts/setup_cognito.sh to auto-create and fill these values.
13+
# Or provide your own Cognito User Pool details.
14+
AGENTCORE_GATEWAY_TOKEN_ENDPOINT=PLACEHOLDER
15+
AGENTCORE_GATEWAY_CLIENT_ID=PLACEHOLDER
16+
AGENTCORE_GATEWAY_CLIENT_SECRET=PLACEHOLDER
1117
AGENTCORE_GATEWAY_OAUTH_SCOPES=agentcore/invoke
12-
AGENTCORE_GATEWAY_CLIENT_ID=your-cognito-client-id
13-
AGENTCORE_GATEWAY_CLIENT_SECRET=your-cognito-client-secret
18+
COGNITO_DISCOVERY_URL=PLACEHOLDER
19+
COGNITO_USER_POOL_ID=PLACEHOLDER
20+
21+
# ─── AgentCore Identity Credential Provider
22+
# Name used by @requires_access_token decorator in the agent code.
23+
# The deploy script registers this credential with AgentCore Identity.
24+
AGENTCORE_GATEWAY_CREDENTIAL_PROVIDER=cognito-gateway-m2m
25+
26+
# ─── Models (cost routing)
27+
# Primary model for MEDIUM/HIGH priority claims (full reasoning).
28+
AGENT_MODEL_ID=global.anthropic.claude-sonnet-4-6
29+
# Fast model for the Validation Agent — classification task, no tool use.
30+
# Haiku is ~5x cheaper and 3-8s faster per invocation.
31+
FAST_MODEL_ID=us.anthropic.claude-haiku-4-5-20251001-v1:0
32+
33+
# ─── Routing
34+
# Confidence threshold (0-100) for auto-approval. Claims scoring at or above
35+
# this value are approved without human review. Lower = more auto-approvals.
36+
AUTO_APPROVE_THRESHOLD=80
37+
38+
# ─── Memory Retrieval Tuning
39+
# Number of prior facts/sessions to retrieve per invocation.
40+
# MEMORY_RETRIEVAL_TOP_K=5
41+
# Minimum relevance score (0.0-1.0) for memory retrieval results.
42+
# MEMORY_RETRIEVAL_RELEVANCE=0.5
1443

15-
# Model (optional — defaults to global.anthropic.claude-sonnet-4-6)
16-
# AGENT_MODEL_ID=global.anthropic.claude-sonnet-4-6
44+
# ─── Infrastructure (CDK)
45+
# Whether to destroy all data on stack delete (true for dev, false for prod).
46+
# Modify in agentcore/cdk/lib/cdk-stack.ts → destroyOnDelete prop.
47+
# DESTROY_ON_DELETE is not an env var — change it in cdk-stack.ts directly.
1748

18-
# Memory (optional — agent works without memory; get MEMORY_ID from deployed stack)
19-
# MEMORY_ID=your-memory-id
49+
# ─── SES (optional — notification Lambda sender email)
50+
# Must be SES-verified in your account for emails to actually send.
51+
# SENDER_EMAIL=noreply@example.com

02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ cdk.out/
1919
# AWS
2020
.env
2121
.env.local
22+
.cognito-state.json
2223
cdk.context.json
2324
cdk-outputs.json
2425
agentcore/cdk/cdk.out/

02-use-cases/02-workflow-automation-agents/event-driven-claims-agent/AGENTS.md

Lines changed: 66 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22

33
> **For humans:** This file provides context for AI coding assistants (Kiro, Cursor, Claude Code, GitHub Copilot). For the human-readable documentation, see [docs/](./docs/README.md), [README.md](./README.md), or [docs/tutorial.md](./docs/tutorial.md).
44
5-
This project is an **event-driven insurance claims processor** built on Amazon Bedrock AgentCore. It uses a dual-agent architecture (Claims Processor + Validation Agent) and deploys as a single CloudFormation stack (`AgentCore-ClaimsAgent-dev`) via the AgentCore CLI.
5+
This project is an **event-driven insurance claims processor** built on Amazon Bedrock AgentCore. It uses a dual-agent architecture (Claims Processor + Validation Agent) with cost-based model routing (Sonnet for reasoning, Haiku for validation) and a deterministic execution phase. Deploys as a single CloudFormation stack (`AgentCore-ClaimsAgent-dev`) via the AgentCore CLI.
66

7-
> **Important:** AgentCore resources (Runtime, Gateway, Memory, PolicyEngine, OnlineEval) are declared in `agentcore/agentcore.json` and managed by the AgentCore CLI. Supplementary infrastructure (DynamoDB, Lambda tools, SNS, S3, Cognito, EventBridge) is defined in the TypeScript CDK app at `agentcore/cdk/lib/infra-construct.ts`. Use `agentcore validate` and `agentcore dev` while iterating; run `agentcore deploy --target dev` to deploy everything together.
7+
> **Important:** AgentCore resources (Runtime, Gateway, Memory, PolicyEngine, OnlineEval) are declared in `agentcore/agentcore.json` and managed by the AgentCore CLI. Supplementary infrastructure (DynamoDB, Lambda tools, SNS, S3, EventBridge) is defined in the TypeScript CDK app at `agentcore/cdk/lib/infra-construct.ts`. The Cognito User Pool (Gateway M2M auth) is managed by `scripts/setup_cognito.sh` (AWS CLI, not CDK). Use `agentcore validate` and `agentcore dev` while iterating; run `agentcore deploy --target dev` to deploy everything together.
88
99
---
1010

@@ -14,16 +14,18 @@ This project is an **event-driven insurance claims processor** built on Amazon B
1414
S3 upload (claims-inbox/)
1515
→ EventBridge rule
1616
→ Trigger Lambda (lambdas/trigger/handler.py)
17-
reads S3 object, gets Cognito M2M JWT, invokes Runtime via HTTPS
17+
reads S3 object, invokes Runtime via SigV4-signed HTTPS (fire-and-forget)
1818
→ AgentCore Runtime (Container: app/claimsagent/)
19-
Phase 1: Claims Processor → lookup_policy → ACCEPT/REJECT decision
20-
Phase 2: Validation Agent → reviews decision → CONFIDENCE + ROUTING
21-
Phase 3: Execution → create_claim / human_review / send_notification
22-
→ AgentCore Gateway (MCP, Cognito M2M auth, Cedar policy enforcement)
19+
Phase 1: Claims Processor (Sonnet) → lookup_policy → ACCEPT/REJECT decision
20+
Phase 2: Validation Agent (Haiku) → reviews decision → CONFIDENCE + ROUTING
21+
Phase 3: Deterministic Execution (no LLM) → create_claim / human_review / send_notification
22+
→ AgentCore Gateway (MCP, Cognito CUSTOM_JWT auth, Cedar policy enforcement)
2323
→ 6 Lambda tool functions (lambdas/<tool>/handler.py)
2424
```
2525

26-
**Auth:** All callers use Cognito M2M JWT (`client_credentials` flow) — not SigV4.
26+
**Auth (two separate paths):**
27+
- **Inbound to Runtime (Trigger Lambda → Runtime):** AWS_IAM (SigV4). The Trigger Lambda's execution role has `bedrock-agentcore:InvokeAgentRuntime` permission granted by CDK via `runtime.grantInvoke(triggerFn)`. No Cognito credentials needed.
28+
- **Outbound from Runtime to Gateway (Runtime → MCP Gateway):** Cognito M2M JWT via `@requires_access_token(provider_name="cognito-gateway-m2m", auth_flow="M2M")` decorator. Secrets managed by AgentCore Identity vault (registered via `agentcore add credential`). The Gateway validates JWT via CUSTOM_JWT authorizer (Cognito OIDC discovery).
2729

2830
---
2931

@@ -37,13 +39,15 @@ event-driven-claims-agent/
3739
├── deploy.sh # One-command deploy (runs CDK)
3840
├── app/claimsagent/
3941
│ ├── Dockerfile # Multi-stage, Python 3.12, ARM64
40-
│ ├── main.py # All agent logic: prompts, agents, routing
41-
│ ├── model/load.py # BedrockModel (global.anthropic.claude-sonnet-4-6)
42-
│ ├── mcp_client/client.py # Stub — MCPClient is configured in main.py
43-
│ └── requirements.txt # Add new runtime deps HERE (used by Dockerfile)
42+
│ ├── main.py # All agent logic: prompts, agents, Identity-managed Gateway OAuth
43+
│ ├── config.py # Centralized env var reads (Gateway, Memory, Model)
44+
│ ├── routing.py # Phase-3 routing: decide_action, resolve_decision/routing
45+
│ ├── memory/session.py # AgentCoreMemorySessionManager (graceful degradation)
46+
│ ├── tools/structured_output.py # @tool decorators: submit_decision, submit_validation
47+
│ └── pyproject.toml # Dependencies (uv-managed)
4448
├── lambdas/ # One directory per Gateway tool
4549
│ ├── schemas/ # MCP tool schemas (JSON) — matched by CDK
46-
│ ├── trigger/handler.py # EventBridge → Runtime invocation
50+
│ ├── trigger/handler.py # EventBridge → Runtime invocation (SigV4 auth)
4751
│ ├── create_claim/handler.py # DDB put on ClaimsTable
4852
│ ├── policy_lookup/handler.py # DDB get on PoliciesTable
4953
│ ├── list_pending_claims/handler.py # DDB scan for pending_review claims
@@ -54,23 +58,34 @@ event-driven-claims-agent/
5458
│ ├── agentcore.json # Declarative AgentCore resources (Runtime/Gateway/Memory/PolicyEngine/Eval)
5559
│ ├── aws-targets.json # Deployment targets (account + region)
5660
│ └── cdk/lib/
57-
│ ├── infra-construct.ts # Supplementary AWS infra (DynamoDB, S3, SNS, Cognito, EventBridge, Lambdas)
61+
│ ├── infra-construct.ts # Supplementary AWS infra (DynamoDB, S3, SNS, EventBridge, Lambdas — Cognito is script-managed)
5862
│ └── cdk-stack.ts # Integration: wires infra ARNs + JWT authorizer + runtime env vars
5963
├── scripts/
6064
│ ├── deploy.sh # Deploy helper
65+
│ ├── destroy.sh # Unified teardown (observability → stack → orphans → Cognito → state)
66+
│ ├── cleanup_agentcore.py # Delete orphaned AgentCore control-plane resources (boto3)
67+
│ ├── setup_cognito.sh # Create Cognito User Pool via AWS CLI (not CDK)
68+
│ ├── teardown_cognito.sh # Delete Cognito if script-created
69+
│ ├── enable_observability.py # Enable Transaction Search + Gateway/Memory deliveries
70+
│ ├── disable_observability.py # Clean up observability deliveries
6171
│ ├── seed_dynamodb.py # Populate test policies
62-
│ ├── test_invoke.py # Direct Runtime invocation (JWT auth)
72+
│ ├── test_invoke.py # Direct Runtime invocation (SigV4 auth)
73+
│ ├── test_auth.py # Authentication pattern tests (6 scenarios)
6374
│ ├── test_e2e.py # Full E2E test suite (5 scenarios)
6475
│ ├── test_cedar.py # Cedar policy enforcement tests
6576
│ ├── test_local.py # Local dev invocation helper
6677
│ └── lint.sh # py_compile + ruff checks
78+
├── tests/ # Offline unit tests (pytest)
79+
│ ├── test_routing.py # Phase-3 routing logic
80+
│ ├── test_structured_output.py # submit_decision / submit_validation tools
81+
│ ├── test_lambda_handlers.py # Lambda tool handlers
82+
│ ├── test_trigger.py # Trigger Lambda
83+
│ └── sample-claim-email.txt # Email for E2E test 5 (uses POL-67890)
6784
├── docs/
6885
│ ├── ARCHITECTURE.md # System design and data flows
6986
│ ├── deployment.md # Step-by-step deploy, verify, teardown
7087
│ ├── decisions/ # Architectural decision records (ADR-0001..0010)
7188
│ └── CONFIGURATION.md # All config surfaces reference
72-
└── tests/
73-
└── sample-claim-email.txt # Email for E2E test 5 (uses POL-67890)
7489
```
7590

7691
---
@@ -88,9 +103,11 @@ This runs: configure target → npm install (CDK) → uv sync (agent) → `agent
88103
```bash
89104
agentcore validate # validate agentcore.json
90105
agentcore deploy --target dev --yes # deploy everything
91-
agentcore destroy --target dev --yes # tear down
92106

93-
# Drive the underlying TypeScript CDK directly:
107+
# NOTE: agentcore CLI does NOT have a destroy command. Use the destroy script:
108+
./scripts/destroy.sh us-west-2 # full teardown (handles DELETE_FAILED + orphans)
109+
110+
# Or drive the underlying TypeScript CDK directly:
94111
cd agentcore/cdk && npm install && npx cdk diff
95112
```
96113

@@ -106,6 +123,19 @@ python3 scripts/test_e2e.py --region us-west-2
106123
python3 scripts/test_e2e.py --region us-west-2 --test 2 # Cedar block test
107124
```
108125

126+
### Run authentication pattern tests
127+
```bash
128+
python3 scripts/test_auth.py --region us-west-2 # All 6 auth tests
129+
python3 scripts/test_auth.py --region us-west-2 --test 3 # Single test (Runtime→Gateway M2M)
130+
```
131+
Validates: (1) SigV4→Runtime succeeds, (2) JWT→IAM Runtime rejected, (3) Runtime→Gateway M2M
132+
works via tool call, (4) no-auth rejected, (5) invalid JWT rejected, (6) wrong scope rejected.
133+
134+
### Run unit tests (offline)
135+
```bash
136+
python3 -m pytest tests/ # routing, structured output, lambda handlers, trigger
137+
```
138+
109139
### Lint
110140
```bash
111141
./scripts/lint.sh
@@ -119,9 +149,12 @@ find app/ lambdas/ scripts/ -name "*.py" -exec python3 -m py_compile {} \;
119149

120150
1. **Lambda handlers return `json.dumps({...})` directly** — no `{statusCode, body}` envelope. The Gateway strips the HTTP wrapper.
121151
2. **Agent routing controls claim status** — the `create_claim` Lambda accepts `status` and `decision` as optional parameters from the agent. Do not add routing logic to the Lambda itself.
122-
3. **Tool schemas live in `lambdas/schemas/`** — each file maps to a Gateway target in the CDK stack via `ToolSchema.from_local_asset(...)`. Keep schemas in sync with Lambda parameters.
123-
4. **Container build, not CodeZip** — runtime deps go in `app/claimsagent/requirements.txt`. The Dockerfile installs from this file.
124-
5. **`agentcore/agentcore.json` is the source of truth for AgentCore resources** (Runtime, Gateway, Memory, PolicyEngine, OnlineEval). Supplementary AWS infra is in `agentcore/cdk/lib/infra-construct.ts`; `cdk-stack.ts` wires the two together (patches Lambda ARNs + the Gateway CUSTOM_JWT authorizer, injects runtime env vars). Don't hand-edit generated CDK output.
152+
3. **Tool schemas live in `lambdas/schemas/`** — each file maps to a Gateway target in the CDK stack via the `toolSchemaFile` field in `agentcore.json`. Keep schemas in sync with Lambda parameters.
153+
4. **Container build, not CodeZip** — runtime deps go in `app/claimsagent/pyproject.toml` (managed by `uv`). The Dockerfile runs `uv sync --frozen`.
154+
5. **`agentcore/agentcore.json` is the source of truth for AgentCore resources** (Runtime, Gateway, Memory, PolicyEngine, OnlineEval). Supplementary AWS infra is in `agentcore/cdk/lib/infra-construct.ts`; `cdk-stack.ts` wires the two together (patches Lambda ARNs + the Gateway CUSTOM_JWT authorizer discovery URL, injects runtime env vars). Don't hand-edit generated CDK output.
155+
6. **Two auth paths:** Inbound to Runtime uses AWS_IAM (SigV4) — CDK grants `runtime.grantInvoke()` to the Trigger Lambda. Outbound from Runtime to Gateway uses Cognito M2M JWT via `@requires_access_token(provider_name="cognito-gateway-m2m", auth_flow="M2M")` — secrets live in AgentCore Identity vault, not env vars.
156+
7. **Structured output tools** (`tools/structured_output.py`) — the agent calls `submit_decision` and `submit_validation` to produce machine-parseable results. When agents fail to call these tools, routing defaults to safe fallbacks (REJECT for missing decision, HUMAN_REVIEW for missing validation).
157+
8. **Phase 3 is deterministic (no LLM call)** — once routing is resolved, tool calls are made directly via `MCPClient.call_tool_async()` using structured data from Phase 1/2. This saves one Sonnet invocation per request. All Phase 3 actions are non-fatal (log + continue on failure).
125158

126159
---
127160

@@ -131,28 +164,27 @@ find app/ lambdas/ scripts/ -name "*.py" -exec python3 -m py_compile {} \;
131164
| Variable | Purpose |
132165
|---|---|
133166
| `AGENTCORE_GATEWAY_URL` | MCP Gateway HTTPS endpoint |
134-
| `AGENTCORE_GATEWAY_TOKEN_ENDPOINT` | Cognito OAuth2 token URL |
167+
| `AGENTCORE_GATEWAY_CREDENTIAL_PROVIDER` | Identity credential provider name (no secrets) |
135168
| `AGENTCORE_GATEWAY_OAUTH_SCOPES` | `agentcore/invoke` |
136-
| `AGENTCORE_GATEWAY_CLIENT_ID` | Cognito app client ID |
137-
| `AGENTCORE_GATEWAY_CLIENT_SECRET` | Cognito app client secret |
169+
| `AGENT_OBSERVABILITY_ENABLED` | `true` — enables OTEL instrumentation |
170+
| `OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT` | `true` — captures LLM messages in traces |
171+
| `AGENT_MODEL_ID` | `global.anthropic.claude-sonnet-4-6` |
172+
| `FAST_MODEL_ID` | `us.anthropic.claude-haiku-4-5-20251001-v1:0` — used by Validation Agent (Phase 2) |
173+
| `AUTO_APPROVE_THRESHOLD` | `80` — confidence threshold for auto-approval |
138174

139175
### Lambda functions (set by CDK)
140176
| Variable | Lambda(s) | Value |
141177
|---|---|---|
142-
| `CLAIMS_TABLE` | create_claim, list_pending, resolve_claim | `ClaimsAgent-Claims` |
143-
| `POLICIES_TABLE` | policy_lookup | `ClaimsAgent-Policies` |
144-
| `REVIEWS_TABLE` | human_review, resolve_claim | `ClaimsAgent-Reviews` |
178+
| `CLAIMS_TABLE` | create_claim, list_pending, resolve_claim | `ClaimsAgent-dev-Claims` |
179+
| `POLICIES_TABLE` | policy_lookup | `ClaimsAgent-dev-Policies` |
180+
| `REVIEWS_TABLE` | human_review, resolve_claim | `ClaimsAgent-dev-Reviews` |
145181
| `REVIEW_SNS_TOPIC_ARN` | human_review | SNS topic ARN |
146182
| `SENDER_EMAIL` | notification | SES verified sender |
147183

148184
### Trigger Lambda (set by CDK)
149185
| Variable | Purpose |
150186
|---|---|
151-
| `AGENTCORE_RUNTIME_ARN` | Runtime ARN for HTTPS invocation |
152-
| `COGNITO_USER_POOL_ID` | For M2M token retrieval |
153-
| `COGNITO_CLIENT_ID` | M2M client |
154-
| `COGNITO_CLIENT_SECRET` | M2M secret |
155-
| `COGNITO_TOKEN_ENDPOINT` | OAuth2 token URL |
187+
| `AGENTCORE_RUNTIME_ARN` | Runtime ARN for SigV4-signed HTTPS invocation |
156188

157189
---
158190

@@ -163,6 +195,7 @@ find app/ lambdas/ scripts/ -name "*.py" -exec python3 -m py_compile {} \;
163195
| `POL-12345` | John Smith | auto | $50,000 | active |
164196
| `POL-67890` | Jane Doe | home | $250,000 | active |
165197
| `POL-11111` | Bob Johnson | auto | $75,000 | active |
198+
| `POL-99999` | Alice Williams | auto | $100,000 | expired |
166199

167200
---
168201

0 commit comments

Comments
 (0)