@aws/nx-plugin 1.0.0-rc.55 → 1.0.0-rc.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/migrations.json +13 -3
- package/package.json +1 -1
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.d.ts +6 -0
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js +89 -0
- package/src/migrations/latest/dynamodb-local-remove-optimize-flag/migration.js.map +1 -0
- package/src/migrations/latest/modernize-function-props-cast/migration.js +0 -1
- package/src/migrations/latest/modernize-function-props-cast/migration.js.map +1 -1
- package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js +0 -1
- package/src/migrations/latest/order-access-log-delivery-after-bucket-policy/migration.js.map +1 -1
- package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js +0 -2
- package/src/migrations/latest/restrict-cors-to-custom-domains/migration.js.map +1 -1
- package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js +0 -1
- package/src/migrations/latest/terraform-bootstrap-adopt-existing-bucket/migration.js.map +1 -1
- package/src/migrations/latest/ts-agent-session-management-support/migration.d.ts +6 -0
- package/src/migrations/latest/ts-agent-session-management-support/migration.js +449 -0
- package/src/migrations/latest/ts-agent-session-management-support/migration.js.map +1 -0
- package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js +0 -2
- package/src/migrations/latest/user-identity-waf-allow-localhost-callback/migration.js.map +1 -1
- package/src/py/agent/__snapshots__/generator.constructs.spec.ts.snap +3 -1
- package/src/py/agent/__snapshots__/generator.frameworks.spec.ts.snap +12 -12
- package/src/py/agent/__snapshots__/generator.protocols.spec.ts.snap +1 -1
- package/src/py/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +2 -1
- package/src/py/agent/a2a-connection/files/agent-connection/app/__targetAgentSnakeCase___client_strands.py.template +2 -1
- package/src/py/agent/a2a-connection/files/langchain/agent-connection/app/__targetAgentSnakeCase___client_langchain.py.template +2 -1
- package/src/py/agent/generator.js +4 -0
- package/src/py/agent/generator.js.map +1 -1
- package/src/py/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +2 -1
- package/src/py/agent/mcp-connection/files/agent-connection/app/__mcpServerSnakeCase___client_strands.py.template +2 -1
- package/src/py/agent/mcp-connection/files/langchain/agent-connection/app/__mcpServerSnakeCase___client_langchain.py.template +2 -1
- package/src/py/agent/react-connection/__snapshots__/generator.spec.ts.snap +6 -0
- package/src/py/agent/schema.d.js.map +1 -1
- package/src/py/agent/schema.d.ts +3 -0
- package/src/py/agent/schema.json +8 -0
- package/src/py/dynamodb/__snapshots__/generator.spec.ts.snap +0 -2
- package/src/py/mcp-server/__snapshots__/generator.spec.ts.snap +4 -2
- package/src/ts/agent/__snapshots__/generator.spec.ts.snap +663 -19
- package/src/ts/agent/a2a-connection/__snapshots__/generator.spec.ts.snap +2 -1
- package/src/ts/agent/a2a-connection/files/agent-connection/app/__targetAgentKebabCase__-client-strands.ts.template +1 -1
- package/src/ts/agent/files/ag-ui/index.ts.template +10 -1
- package/src/ts/agent/files/common/agent.ts.template +11 -3
- package/src/ts/agent/files/common/session.ts.template +43 -0
- package/src/ts/agent/gateway-connection/__snapshots__/generator.spec.ts.snap +1 -0
- package/src/ts/agent/generator.d.ts +4 -0
- package/src/ts/agent/generator.js +21 -0
- package/src/ts/agent/generator.js.map +1 -1
- package/src/ts/agent/mcp-connection/__snapshots__/generator.spec.ts.snap +2 -1
- package/src/ts/agent/mcp-connection/files/agent-connection/app/__mcpServerKebabCase__-client-strands.ts.template +2 -1
- package/src/ts/agent/react-connection/__snapshots__/generator.spec.ts.snap +8 -4
- package/src/ts/agent/react-connection/files/src/components/__agentNameClassName__AgentClientProvider.tsx.template +2 -1
- package/src/ts/agent/schema.d.js.map +1 -1
- package/src/ts/agent/schema.d.ts +3 -0
- package/src/ts/agent/schema.json +8 -0
- package/src/ts/dynamodb/__snapshots__/generator.spec.ts.snap +0 -2
- package/src/ts/mcp-server/__snapshots__/generator.spec.ts.snap +4 -2
- package/src/ts/nx-migration/files/migration.ts.template +4 -0
- package/src/utils/agent-chat/files/common/agentcore.ts.template +2 -2
- package/src/utils/agent-connection/agent-connection.js +4 -0
- package/src/utils/agent-connection/agent-connection.js.map +1 -1
- package/src/utils/agent-connection/files/core-runtime-config/runtime-config.ts.template +11 -1
- package/src/utils/agent-connection/files/core-strands/base/model-errors-strands.ts.template +26 -15
- package/src/utils/agent-connection/files/core-strands/base/tool-errors-strands.ts.template +23 -16
- package/src/utils/agent-connection/files/py-core-runtime-config/runtime_config.py.template +4 -3
- package/src/utils/agent-core-constructs/agent-core-constructs.d.ts +4 -0
- package/src/utils/agent-core-constructs/agent-core-constructs.js +7 -1
- package/src/utils/agent-core-constructs/agent-core-constructs.js.map +1 -1
- package/src/utils/agent-core-constructs/files/cdk/app/agent-core/__nameKebabCase__/__nameKebabCase__.ts.template +131 -3
- package/src/utils/agent-core-constructs/files/terraform/app/agent-core/__nameKebabCase__/__nameKebabCase__.tf.template +180 -1
- package/src/utils/ast.d.ts +5 -0
- package/src/utils/ast.js +25 -0
- package/src/utils/ast.js.map +1 -1
- package/src/utils/connection/open-api/files/components/__apiNameClassName__Provider.tsx.template +2 -0
- package/src/utils/files/common/scripts/src/dynamodb/start-container.ts.template +0 -1
- package/src/utils/migration-versions.d.ts +15 -10
- package/src/utils/migration-versions.js +48 -36
- package/src/utils/migration-versions.js.map +1 -1
- package/src/utils/version-upgrade-migration/nx-package-updates.d.ts +18 -8
- package/src/utils/version-upgrade-migration/nx-package-updates.js +19 -11
- package/src/utils/version-upgrade-migration/nx-package-updates.js.map +1 -1
- package/src/utils/version-upgrade-migration/register.d.ts +6 -1
- package/src/utils/version-upgrade-migration/register.js +8 -3
- package/src/utils/version-upgrade-migration/register.js.map +1 -1
|
@@ -29,8 +29,8 @@ export const resolveRemoteAgent = async (): Promise<
|
|
|
29
29
|
application,
|
|
30
30
|
environment: 'default',
|
|
31
31
|
transform: 'json',
|
|
32
|
-
})) as { agentRuntimes?: Record<string, string> };
|
|
33
|
-
const arn = config?.agentRuntimes?.['TestProjectAgent'];
|
|
32
|
+
})) as { agentRuntimes?: Record<string, { arn: string }> };
|
|
33
|
+
const arn = config?.agentRuntimes?.['TestProjectAgent']?.arn;
|
|
34
34
|
if (!arn) {
|
|
35
35
|
throw new Error(
|
|
36
36
|
\`No deployed agent named 'TestProjectAgent' found in runtime configuration (application \${application}).\`,
|
|
@@ -131,8 +131,8 @@ export const resolveRemoteAgent = async (): Promise<
|
|
|
131
131
|
application,
|
|
132
132
|
environment: 'default',
|
|
133
133
|
transform: 'json',
|
|
134
|
-
})) as { agentRuntimes?: Record<string, string> };
|
|
135
|
-
const arn = config?.agentRuntimes?.['TestProjectAgent'];
|
|
134
|
+
})) as { agentRuntimes?: Record<string, { arn: string }> };
|
|
135
|
+
const arn = config?.agentRuntimes?.['TestProjectAgent']?.arn;
|
|
136
136
|
if (!arn) {
|
|
137
137
|
throw new Error(
|
|
138
138
|
\`No deployed agent named 'TestProjectAgent' found in runtime configuration (application \${application}).\`,
|
|
@@ -224,8 +224,8 @@ export const resolveRemoteAgent = async (): Promise<
|
|
|
224
224
|
application,
|
|
225
225
|
environment: 'default',
|
|
226
226
|
transform: 'json',
|
|
227
|
-
})) as { agentRuntimes?: Record<string, string> };
|
|
228
|
-
const arn = config?.agentRuntimes?.['TestProjectAgent'];
|
|
227
|
+
})) as { agentRuntimes?: Record<string, { arn: string }> };
|
|
228
|
+
const arn = config?.agentRuntimes?.['TestProjectAgent']?.arn;
|
|
229
229
|
if (!arn) {
|
|
230
230
|
throw new Error(
|
|
231
231
|
\`No deployed agent named 'TestProjectAgent' found in runtime configuration (application \${application}).\`,
|
|
@@ -308,8 +308,8 @@ export const resolveRemoteAgent = async (): Promise<
|
|
|
308
308
|
application,
|
|
309
309
|
environment: 'default',
|
|
310
310
|
transform: 'json',
|
|
311
|
-
})) as { agentRuntimes?: Record<string, string> };
|
|
312
|
-
const arn = config?.agentRuntimes?.['TestProjectAgent'];
|
|
311
|
+
})) as { agentRuntimes?: Record<string, { arn: string }> };
|
|
312
|
+
const arn = config?.agentRuntimes?.['TestProjectAgent']?.arn;
|
|
313
313
|
if (!arn) {
|
|
314
314
|
throw new Error(
|
|
315
315
|
\`No deployed agent named 'TestProjectAgent' found in runtime configuration (application \${application}).\`,
|
|
@@ -383,8 +383,8 @@ export const resolveRemoteAgent = async (): Promise<
|
|
|
383
383
|
application,
|
|
384
384
|
environment: 'default',
|
|
385
385
|
transform: 'json',
|
|
386
|
-
})) as { agentRuntimes?: Record<string, string> };
|
|
387
|
-
const arn = config?.agentRuntimes?.['TestProjectAgent'];
|
|
386
|
+
})) as { agentRuntimes?: Record<string, { arn: string }> };
|
|
387
|
+
const arn = config?.agentRuntimes?.['TestProjectAgent']?.arn;
|
|
388
388
|
if (!arn) {
|
|
389
389
|
throw new Error(
|
|
390
390
|
\`No deployed agent named 'TestProjectAgent' found in runtime configuration (application \${application}).\`,
|
|
@@ -493,8 +493,8 @@ export const resolveRemoteAgent = async (): Promise<
|
|
|
493
493
|
application,
|
|
494
494
|
environment: 'default',
|
|
495
495
|
transform: 'json',
|
|
496
|
-
})) as { agentRuntimes?: Record<string, string> };
|
|
497
|
-
const arn = config?.agentRuntimes?.['TestProjectAgent'];
|
|
496
|
+
})) as { agentRuntimes?: Record<string, { arn: string }> };
|
|
497
|
+
const arn = config?.agentRuntimes?.['TestProjectAgent']?.arn;
|
|
498
498
|
if (!arn) {
|
|
499
499
|
throw new Error(
|
|
500
500
|
\`No deployed agent named 'TestProjectAgent' found in runtime configuration (application \${application}).\`,
|
|
@@ -564,6 +564,81 @@ await chatLoop(new TrpcWebSocketAdapter(), process.env.URL ?? '');
|
|
|
564
564
|
"
|
|
565
565
|
`;
|
|
566
566
|
|
|
567
|
+
exports[`ts#agent generator > should generate session.ts using S3 storage by default > session.ts (s3) 1`] = `
|
|
568
|
+
"import { SessionManager } from '@strands-agents/sdk';
|
|
569
|
+
import { LocalFileStorage, S3Storage } from '@strands-agents/sdk/storage';
|
|
570
|
+
import {
|
|
571
|
+
getCurrentSessionId,
|
|
572
|
+
getAgentCoreRuntimeConfig,
|
|
573
|
+
} from '@proj/agent-connection';
|
|
574
|
+
|
|
575
|
+
/**
|
|
576
|
+
* Returns a SessionManager for persisting conversation state across
|
|
577
|
+
* invocations. Local development always uses local file storage for
|
|
578
|
+
* convenience, regardless of the configured session option. Without a
|
|
579
|
+
* configured session option, conversation state is kept in memory only and
|
|
580
|
+
* does not survive process restarts.
|
|
581
|
+
*/
|
|
582
|
+
export const getSessionManager = async (): Promise<SessionManager> => {
|
|
583
|
+
const sessionId = getCurrentSessionId();
|
|
584
|
+
if (!sessionId) {
|
|
585
|
+
throw new Error(
|
|
586
|
+
'No current session id — cannot resolve a SessionManager outside of a request scope.',
|
|
587
|
+
);
|
|
588
|
+
}
|
|
589
|
+
if (process.env.LOCAL_DEV === 'true') {
|
|
590
|
+
return new SessionManager({
|
|
591
|
+
sessionId,
|
|
592
|
+
storage: new LocalFileStorage(
|
|
593
|
+
'../../tmp/agents/strands/test-project-agent',
|
|
594
|
+
),
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
const config = await getAgentCoreRuntimeConfig();
|
|
598
|
+
const bucketName =
|
|
599
|
+
config.agentRuntimes?.['TestProjectAgent']?.session?.bucketName;
|
|
600
|
+
if (!bucketName) {
|
|
601
|
+
throw new Error(
|
|
602
|
+
"No S3 bucket configured for this agent's session in runtime configuration.",
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
return new SessionManager({ sessionId, storage: new S3Storage(bucketName) });
|
|
606
|
+
};
|
|
607
|
+
"
|
|
608
|
+
`;
|
|
609
|
+
|
|
610
|
+
exports[`ts#agent generator > should generate session.ts using in-memory storage when session is in-memory > session.ts (in-memory) 1`] = `
|
|
611
|
+
"import { SessionManager } from '@strands-agents/sdk';
|
|
612
|
+
import { LocalFileStorage, InMemoryStorage } from '@strands-agents/sdk/storage';
|
|
613
|
+
import { getCurrentSessionId } from '@proj/agent-connection';
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Returns a SessionManager for persisting conversation state across
|
|
617
|
+
* invocations. Local development always uses local file storage for
|
|
618
|
+
* convenience, regardless of the configured session option. Without a
|
|
619
|
+
* configured session option, conversation state is kept in memory only and
|
|
620
|
+
* does not survive process restarts.
|
|
621
|
+
*/
|
|
622
|
+
export const getSessionManager = async (): Promise<SessionManager> => {
|
|
623
|
+
const sessionId = getCurrentSessionId();
|
|
624
|
+
if (!sessionId) {
|
|
625
|
+
throw new Error(
|
|
626
|
+
'No current session id — cannot resolve a SessionManager outside of a request scope.',
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
if (process.env.LOCAL_DEV === 'true') {
|
|
630
|
+
return new SessionManager({
|
|
631
|
+
sessionId,
|
|
632
|
+
storage: new LocalFileStorage(
|
|
633
|
+
'../../tmp/agents/strands/test-project-agent',
|
|
634
|
+
),
|
|
635
|
+
});
|
|
636
|
+
}
|
|
637
|
+
return new SessionManager({ sessionId, storage: new InMemoryStorage() });
|
|
638
|
+
};
|
|
639
|
+
"
|
|
640
|
+
`;
|
|
641
|
+
|
|
567
642
|
exports[`ts#agent generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > agent-Dockerfile 1`] = `
|
|
568
643
|
"FROM public.ecr.aws/docker/library/node:lts-slim
|
|
569
644
|
|
|
@@ -596,9 +671,22 @@ CMD [ "node", "--require", "@aws/aws-distro-opentelemetry-node-autoinstrumentati
|
|
|
596
671
|
`;
|
|
597
672
|
|
|
598
673
|
exports[`ts#agent generator > should match snapshot for BedrockAgentCoreRuntime generated constructs files > agent-construct.ts 1`] = `
|
|
599
|
-
"import { Fn, Lazy, Names, Stack } from 'aws-cdk-lib';
|
|
674
|
+
"import { Fn, Lazy, Names, RemovalPolicy, Stack } from 'aws-cdk-lib';
|
|
600
675
|
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
|
|
601
676
|
import { Connections, IConnectable } from 'aws-cdk-lib/aws-ec2';
|
|
677
|
+
import {
|
|
678
|
+
BlockPublicAccess,
|
|
679
|
+
Bucket,
|
|
680
|
+
BucketEncryption,
|
|
681
|
+
} from 'aws-cdk-lib/aws-s3';
|
|
682
|
+
import { Key } from 'aws-cdk-lib/aws-kms';
|
|
683
|
+
import {
|
|
684
|
+
CfnDelivery,
|
|
685
|
+
CfnDeliveryDestination,
|
|
686
|
+
CfnDeliverySource,
|
|
687
|
+
LogGroup,
|
|
688
|
+
RetentionDays,
|
|
689
|
+
} from 'aws-cdk-lib/aws-logs';
|
|
602
690
|
import { Construct } from 'constructs';
|
|
603
691
|
import * as path from 'path';
|
|
604
692
|
import * as url from 'url';
|
|
@@ -610,10 +698,13 @@ import {
|
|
|
610
698
|
} from 'aws-cdk-lib/aws-bedrockagentcore';
|
|
611
699
|
import {
|
|
612
700
|
PolicyStatement,
|
|
701
|
+
Effect,
|
|
702
|
+
ServicePrincipal,
|
|
613
703
|
IGrantable,
|
|
614
704
|
IPrincipal,
|
|
615
705
|
Grant,
|
|
616
706
|
} from 'aws-cdk-lib/aws-iam';
|
|
707
|
+
import { suppressRules } from '../../../core/checkov.js';
|
|
617
708
|
import { RuntimeConfig } from '../../../core/runtime-config.js';
|
|
618
709
|
import { findWorkspaceRoot } from '../../../core/workspace.js';
|
|
619
710
|
|
|
@@ -647,6 +738,111 @@ export class SnapshotBedrockAgent
|
|
|
647
738
|
platform: Platform.LINUX_ARM64,
|
|
648
739
|
});
|
|
649
740
|
|
|
741
|
+
const sessionKey = new Key(this, 'SessionKey', {
|
|
742
|
+
enableKeyRotation: true,
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
// Allow CloudWatch Logs to use the session key for server access log delivery.
|
|
746
|
+
const stack = Stack.of(this);
|
|
747
|
+
sessionKey.addToResourcePolicy(
|
|
748
|
+
new PolicyStatement({
|
|
749
|
+
effect: Effect.ALLOW,
|
|
750
|
+
principals: [
|
|
751
|
+
new ServicePrincipal(\`logs.\${stack.region}.amazonaws.com\`),
|
|
752
|
+
],
|
|
753
|
+
actions: [
|
|
754
|
+
'kms:Encrypt',
|
|
755
|
+
'kms:Decrypt',
|
|
756
|
+
'kms:ReEncrypt*',
|
|
757
|
+
'kms:GenerateDataKey*',
|
|
758
|
+
'kms:DescribeKey',
|
|
759
|
+
],
|
|
760
|
+
resources: ['*'],
|
|
761
|
+
conditions: {
|
|
762
|
+
ArnLike: {
|
|
763
|
+
'kms:EncryptionContext:aws:logs:arn': \`arn:aws:logs:\${stack.region}:\${stack.account}:log-group:*\`,
|
|
764
|
+
},
|
|
765
|
+
},
|
|
766
|
+
}),
|
|
767
|
+
);
|
|
768
|
+
|
|
769
|
+
const sessionAccessLogs = new LogGroup(this, 'SessionAccessLogs', {
|
|
770
|
+
retention: RetentionDays.ONE_YEAR,
|
|
771
|
+
encryptionKey: sessionKey,
|
|
772
|
+
removalPolicy: RemovalPolicy.DESTROY,
|
|
773
|
+
});
|
|
774
|
+
|
|
775
|
+
const sessionBucket = new Bucket(this, 'SessionBucket', {
|
|
776
|
+
enforceSSL: true,
|
|
777
|
+
removalPolicy: RemovalPolicy.RETAIN,
|
|
778
|
+
encryption: BucketEncryption.KMS,
|
|
779
|
+
encryptionKey: sessionKey,
|
|
780
|
+
blockPublicAccess: BlockPublicAccess.BLOCK_ALL,
|
|
781
|
+
});
|
|
782
|
+
suppressRules(
|
|
783
|
+
sessionBucket,
|
|
784
|
+
['CKV_AWS_21'],
|
|
785
|
+
'Session data does not need versioning enabled',
|
|
786
|
+
);
|
|
787
|
+
suppressRules(
|
|
788
|
+
sessionBucket,
|
|
789
|
+
['CKV2_AWS_61'],
|
|
790
|
+
'Lifecycle configuration not required for session data',
|
|
791
|
+
);
|
|
792
|
+
suppressRules(
|
|
793
|
+
sessionBucket,
|
|
794
|
+
['CKV_AWS_144'],
|
|
795
|
+
'Cross-region replication not required for session data',
|
|
796
|
+
);
|
|
797
|
+
suppressRules(
|
|
798
|
+
sessionBucket,
|
|
799
|
+
['CKV2_AWS_62'],
|
|
800
|
+
'Event notifications not required for session data',
|
|
801
|
+
);
|
|
802
|
+
suppressRules(
|
|
803
|
+
sessionBucket,
|
|
804
|
+
['CKV_AWS_18'],
|
|
805
|
+
'Server access logs are delivered to CloudWatch Logs',
|
|
806
|
+
);
|
|
807
|
+
|
|
808
|
+
const sessionAccessLogsSource: CfnDeliverySource = new CfnDeliverySource(
|
|
809
|
+
this,
|
|
810
|
+
'SessionAccessLogsSource',
|
|
811
|
+
{
|
|
812
|
+
name: Lazy.string({
|
|
813
|
+
produce: () =>
|
|
814
|
+
Names.uniqueResourceName(sessionAccessLogsSource, {
|
|
815
|
+
maxLength: 60,
|
|
816
|
+
}),
|
|
817
|
+
}),
|
|
818
|
+
logType: 'S3_SERVER_ACCESS_LOGS',
|
|
819
|
+
resourceArn: sessionBucket.bucketArn,
|
|
820
|
+
},
|
|
821
|
+
);
|
|
822
|
+
const sessionBucketPolicy = sessionBucket.policy;
|
|
823
|
+
if (sessionBucketPolicy) {
|
|
824
|
+
sessionAccessLogsSource.node.addDependency(sessionBucketPolicy);
|
|
825
|
+
}
|
|
826
|
+
const sessionAccessLogsDestination: CfnDeliveryDestination =
|
|
827
|
+
new CfnDeliveryDestination(this, 'SessionAccessLogsDestination', {
|
|
828
|
+
name: Lazy.string({
|
|
829
|
+
produce: () =>
|
|
830
|
+
Names.uniqueResourceName(sessionAccessLogsDestination, {
|
|
831
|
+
maxLength: 60,
|
|
832
|
+
}),
|
|
833
|
+
}),
|
|
834
|
+
destinationResourceArn: sessionAccessLogs.logGroupArn,
|
|
835
|
+
});
|
|
836
|
+
const sessionAccessLogsDelivery = new CfnDelivery(
|
|
837
|
+
this,
|
|
838
|
+
'SessionAccessLogsDelivery',
|
|
839
|
+
{
|
|
840
|
+
deliverySourceName: sessionAccessLogsSource.name,
|
|
841
|
+
deliveryDestinationArn: sessionAccessLogsDestination.attrArn,
|
|
842
|
+
},
|
|
843
|
+
);
|
|
844
|
+
sessionAccessLogsDelivery.addDependency(sessionAccessLogsSource);
|
|
845
|
+
|
|
650
846
|
this.agentCoreRuntime = new Runtime(this, 'SnapshotBedrockAgent', {
|
|
651
847
|
runtimeName: Lazy.string({
|
|
652
848
|
produce: () =>
|
|
@@ -675,11 +871,16 @@ export class SnapshotBedrockAgent
|
|
|
675
871
|
}),
|
|
676
872
|
);
|
|
677
873
|
|
|
874
|
+
sessionBucket.grantReadWrite(this.agentCoreRuntime);
|
|
875
|
+
|
|
678
876
|
rc.grantReadAppConfig(this.agentCoreRuntime);
|
|
679
877
|
|
|
680
878
|
rc.set('agentcore', 'agentRuntimes', {
|
|
681
879
|
...rc.get('agentcore').agentRuntimes,
|
|
682
|
-
SnapshotBedrockAgent:
|
|
880
|
+
SnapshotBedrockAgent: {
|
|
881
|
+
arn: this.agentCoreRuntime.agentRuntimeArn,
|
|
882
|
+
session: { bucketName: sessionBucket.bucketName },
|
|
883
|
+
},
|
|
683
884
|
});
|
|
684
885
|
}
|
|
685
886
|
|
|
@@ -754,7 +955,16 @@ export * from './workspace.js';
|
|
|
754
955
|
`;
|
|
755
956
|
|
|
756
957
|
exports[`ts#agent generator > should match snapshot for Terraform generated files > terraform-agent.tf 1`] = `
|
|
757
|
-
"
|
|
958
|
+
"terraform {
|
|
959
|
+
required_providers {
|
|
960
|
+
random = {
|
|
961
|
+
source = "hashicorp/random"
|
|
962
|
+
version = "3.9.0"
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
variable "env" {
|
|
758
968
|
description = "Environment variables to pass to the agent core runtime"
|
|
759
969
|
type = map(string)
|
|
760
970
|
default = {}
|
|
@@ -805,6 +1015,145 @@ variable "appconfig_application_arn" {
|
|
|
805
1015
|
type = string
|
|
806
1016
|
}
|
|
807
1017
|
|
|
1018
|
+
data "aws_region" "current" {}
|
|
1019
|
+
data "aws_caller_identity" "current" {}
|
|
1020
|
+
|
|
1021
|
+
locals {
|
|
1022
|
+
# Delivery source/destination names have a 60 character maximum. Truncate
|
|
1023
|
+
# the agent name so these stay within the limit.
|
|
1024
|
+
session_access_logs_name_prefix = substr("terraform-snapshot-agent", 0, 30)
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
# Uniquifies resource names below so this construct can be deployed more than
|
|
1028
|
+
# once (e.g. across stages) within the same account/region.
|
|
1029
|
+
resource "random_id" "session_unique_suffix" {
|
|
1030
|
+
byte_length = 4
|
|
1031
|
+
}
|
|
1032
|
+
|
|
1033
|
+
# KMS key encrypting the session bucket and its server access logs.
|
|
1034
|
+
resource "aws_kms_key" "session" {
|
|
1035
|
+
description = "KMS key for terraform-snapshot-agent agent session data"
|
|
1036
|
+
enable_key_rotation = true
|
|
1037
|
+
deletion_window_in_days = 7
|
|
1038
|
+
|
|
1039
|
+
policy = jsonencode({
|
|
1040
|
+
Version = "2012-10-17"
|
|
1041
|
+
Statement = [
|
|
1042
|
+
{
|
|
1043
|
+
Sid = "EnableIAMUserPermissions"
|
|
1044
|
+
Effect = "Allow"
|
|
1045
|
+
Principal = { AWS = "arn:aws:iam::\${data.aws_caller_identity.current.account_id}:root" }
|
|
1046
|
+
Action = "kms:*"
|
|
1047
|
+
Resource = "*"
|
|
1048
|
+
},
|
|
1049
|
+
{
|
|
1050
|
+
Sid = "AllowCloudWatchLogs"
|
|
1051
|
+
Effect = "Allow"
|
|
1052
|
+
Principal = { Service = "logs.\${data.aws_region.current.region}.amazonaws.com" }
|
|
1053
|
+
Action = [
|
|
1054
|
+
"kms:Encrypt",
|
|
1055
|
+
"kms:Decrypt",
|
|
1056
|
+
"kms:ReEncrypt*",
|
|
1057
|
+
"kms:GenerateDataKey*",
|
|
1058
|
+
"kms:DescribeKey"
|
|
1059
|
+
]
|
|
1060
|
+
Resource = "*"
|
|
1061
|
+
Condition = {
|
|
1062
|
+
ArnLike = {
|
|
1063
|
+
"kms:EncryptionContext:aws:logs:arn" = "arn:aws:logs:\${data.aws_region.current.region}:\${data.aws_caller_identity.current.account_id}:log-group:*"
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
}
|
|
1067
|
+
]
|
|
1068
|
+
})
|
|
1069
|
+
|
|
1070
|
+
tags = var.tags
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1073
|
+
# CloudWatch log group receiving the session bucket's server access logs.
|
|
1074
|
+
resource "aws_cloudwatch_log_group" "session_access_logs" {
|
|
1075
|
+
name = "/aws/s3/terraform-snapshot-agent-session-access-logs-\${random_id.session_unique_suffix.hex}"
|
|
1076
|
+
retention_in_days = 365
|
|
1077
|
+
kms_key_id = aws_kms_key.session.arn
|
|
1078
|
+
|
|
1079
|
+
tags = var.tags
|
|
1080
|
+
}
|
|
1081
|
+
|
|
1082
|
+
# Bucket storing the agent's session data
|
|
1083
|
+
resource "aws_s3_bucket" "session" {
|
|
1084
|
+
#checkov:skip=CKV2_AWS_61:Lifecycle configuration not required for session data
|
|
1085
|
+
#checkov:skip=CKV_AWS_144:Cross-region replication not required for session data
|
|
1086
|
+
#checkov:skip=CKV2_AWS_62:Event notifications not required for session data
|
|
1087
|
+
#checkov:skip=CKV_AWS_18:Server access logs are delivered to CloudWatch Logs (see aws_cloudwatch_log_delivery.session)
|
|
1088
|
+
#checkov:skip=CKV_AWS_21:Session data does not need versioning enabled
|
|
1089
|
+
force_destroy = false
|
|
1090
|
+
}
|
|
1091
|
+
|
|
1092
|
+
resource "aws_s3_bucket_server_side_encryption_configuration" "session" {
|
|
1093
|
+
bucket = aws_s3_bucket.session.id
|
|
1094
|
+
|
|
1095
|
+
rule {
|
|
1096
|
+
apply_server_side_encryption_by_default {
|
|
1097
|
+
kms_master_key_id = aws_kms_key.session.arn
|
|
1098
|
+
sse_algorithm = "aws:kms"
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
resource "aws_s3_bucket_public_access_block" "session" {
|
|
1104
|
+
bucket = aws_s3_bucket.session.id
|
|
1105
|
+
|
|
1106
|
+
block_public_acls = true
|
|
1107
|
+
block_public_policy = true
|
|
1108
|
+
ignore_public_acls = true
|
|
1109
|
+
restrict_public_buckets = true
|
|
1110
|
+
}
|
|
1111
|
+
|
|
1112
|
+
resource "aws_s3_bucket_policy" "session" {
|
|
1113
|
+
bucket = aws_s3_bucket.session.id
|
|
1114
|
+
|
|
1115
|
+
policy = jsonencode({
|
|
1116
|
+
Version = "2012-10-17"
|
|
1117
|
+
Statement = [
|
|
1118
|
+
{
|
|
1119
|
+
Sid = "DenyInsecureConnections"
|
|
1120
|
+
Effect = "Deny"
|
|
1121
|
+
Principal = "*"
|
|
1122
|
+
Action = "s3:*"
|
|
1123
|
+
Resource = [
|
|
1124
|
+
aws_s3_bucket.session.arn,
|
|
1125
|
+
"\${aws_s3_bucket.session.arn}/*"
|
|
1126
|
+
]
|
|
1127
|
+
Condition = {
|
|
1128
|
+
Bool = {
|
|
1129
|
+
"aws:SecureTransport" = "false"
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
]
|
|
1134
|
+
})
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
# Deliver the session bucket's server access logs to CloudWatch Logs.
|
|
1138
|
+
resource "aws_cloudwatch_log_delivery_source" "session" {
|
|
1139
|
+
name = "\${local.session_access_logs_name_prefix}-access-logs-source-\${random_id.session_unique_suffix.hex}"
|
|
1140
|
+
log_type = "S3_SERVER_ACCESS_LOGS"
|
|
1141
|
+
resource_arn = aws_s3_bucket.session.arn
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
resource "aws_cloudwatch_log_delivery_destination" "session" {
|
|
1145
|
+
name = "\${local.session_access_logs_name_prefix}-access-logs-dest-\${random_id.session_unique_suffix.hex}"
|
|
1146
|
+
|
|
1147
|
+
delivery_destination_configuration {
|
|
1148
|
+
destination_resource_arn = aws_cloudwatch_log_group.session_access_logs.arn
|
|
1149
|
+
}
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
resource "aws_cloudwatch_log_delivery" "session" {
|
|
1153
|
+
delivery_source_name = aws_cloudwatch_log_delivery_source.session.name
|
|
1154
|
+
delivery_destination_arn = aws_cloudwatch_log_delivery_destination.session.arn
|
|
1155
|
+
}
|
|
1156
|
+
|
|
808
1157
|
module "agent_core_runtime" {
|
|
809
1158
|
source = "../../../core/agent-core"
|
|
810
1159
|
agent_runtime_name = "TerraformSnapshotAgent"
|
|
@@ -837,6 +1186,29 @@ module "agent_core_runtime" {
|
|
|
837
1186
|
"arn:aws:bedrock:*:*:foundation-model/*",
|
|
838
1187
|
"arn:aws:bedrock:*:*:inference-profile/*"
|
|
839
1188
|
]
|
|
1189
|
+
},
|
|
1190
|
+
# Grant access for the agent to read/write its session data
|
|
1191
|
+
{
|
|
1192
|
+
Effect = "Allow"
|
|
1193
|
+
Action = [
|
|
1194
|
+
"s3:GetObject",
|
|
1195
|
+
"s3:PutObject",
|
|
1196
|
+
"s3:DeleteObject",
|
|
1197
|
+
"s3:ListBucket"
|
|
1198
|
+
]
|
|
1199
|
+
Resource = [
|
|
1200
|
+
aws_s3_bucket.session.arn,
|
|
1201
|
+
"\${aws_s3_bucket.session.arn}/*"
|
|
1202
|
+
]
|
|
1203
|
+
},
|
|
1204
|
+
# Grant access for the agent to use the session bucket's KMS key
|
|
1205
|
+
{
|
|
1206
|
+
Effect = "Allow"
|
|
1207
|
+
Action = [
|
|
1208
|
+
"kms:Decrypt",
|
|
1209
|
+
"kms:GenerateDataKey*"
|
|
1210
|
+
]
|
|
1211
|
+
Resource = [aws_kms_key.session.arn]
|
|
840
1212
|
}
|
|
841
1213
|
], var.additional_iam_policy_statements)
|
|
842
1214
|
tags = var.tags
|
|
@@ -848,7 +1220,7 @@ module "add_agent_runtime_to_runtime_config" {
|
|
|
848
1220
|
|
|
849
1221
|
namespace = "agentcore"
|
|
850
1222
|
key = "agentRuntimes"
|
|
851
|
-
value = { "TerraformSnapshotAgent" = module.agent_core_runtime.agent_core_runtime_arn }
|
|
1223
|
+
value = { "TerraformSnapshotAgent" = { arn = module.agent_core_runtime.agent_core_runtime_arn, session = { bucketName = aws_s3_bucket.session.bucket } } }
|
|
852
1224
|
|
|
853
1225
|
depends_on = [module.agent_core_runtime]
|
|
854
1226
|
}
|
|
@@ -1391,7 +1763,11 @@ output "security_group_id" {
|
|
|
1391
1763
|
|
|
1392
1764
|
exports[`ts#agent generator > should match snapshot for generated files > agent-agent.ts 1`] = `
|
|
1393
1765
|
"import { Agent, tool } from '@strands-agents/sdk';
|
|
1394
|
-
import {
|
|
1766
|
+
import {
|
|
1767
|
+
ModelErrorLoggingPlugin,
|
|
1768
|
+
ToolErrorLoggingPlugin,
|
|
1769
|
+
} from '@proj/agent-connection';
|
|
1770
|
+
import { getSessionManager } from './session.js';
|
|
1395
1771
|
import { z } from 'zod';
|
|
1396
1772
|
|
|
1397
1773
|
const multiply = tool({
|
|
@@ -1410,9 +1786,9 @@ export const getAgent = async () => {
|
|
|
1410
1786
|
Use your tools for mathematical tasks.
|
|
1411
1787
|
Refer to tools as your 'spellbook'.\`,
|
|
1412
1788
|
tools: [multiply],
|
|
1789
|
+
sessionManager: await getSessionManager(),
|
|
1790
|
+
plugins: [new ModelErrorLoggingPlugin(), new ToolErrorLoggingPlugin()],
|
|
1413
1791
|
});
|
|
1414
|
-
logModelErrors(agent);
|
|
1415
|
-
logToolErrors(agent);
|
|
1416
1792
|
return agent;
|
|
1417
1793
|
};
|
|
1418
1794
|
"
|
|
@@ -1815,3 +2191,271 @@ export function zAsyncIterable<
|
|
|
1815
2191
|
}
|
|
1816
2192
|
"
|
|
1817
2193
|
`;
|
|
2194
|
+
|
|
2195
|
+
exports[`ts#agent generator > should not create session bucket infrastructure when session is in-memory (Terraform) > terraform-agent.tf (in-memory) 1`] = `
|
|
2196
|
+
"variable "env" {
|
|
2197
|
+
description = "Environment variables to pass to the agent core runtime"
|
|
2198
|
+
type = map(string)
|
|
2199
|
+
default = {}
|
|
2200
|
+
}
|
|
2201
|
+
|
|
2202
|
+
variable "additional_iam_policy_statements" {
|
|
2203
|
+
description = "Additional IAM policy statements to attach to the agent core runtime role"
|
|
2204
|
+
type = list(object({
|
|
2205
|
+
Effect = string
|
|
2206
|
+
Action = list(string)
|
|
2207
|
+
Resource = list(string)
|
|
2208
|
+
}))
|
|
2209
|
+
default = []
|
|
2210
|
+
}
|
|
2211
|
+
|
|
2212
|
+
variable "tags" {
|
|
2213
|
+
description = "Tags to apply to resources"
|
|
2214
|
+
type = map(string)
|
|
2215
|
+
default = {}
|
|
2216
|
+
}
|
|
2217
|
+
|
|
2218
|
+
# VPC Configuration (optional)
|
|
2219
|
+
variable "enable_vpc" {
|
|
2220
|
+
description = "Run the agent core runtime inside a VPC. Set alongside vpc_id/subnet_ids."
|
|
2221
|
+
type = bool
|
|
2222
|
+
default = false
|
|
2223
|
+
}
|
|
2224
|
+
|
|
2225
|
+
variable "vpc_id" {
|
|
2226
|
+
description = "VPC ID to run the agent core runtime in. Required when enable_vpc is true."
|
|
2227
|
+
type = string
|
|
2228
|
+
default = null
|
|
2229
|
+
}
|
|
2230
|
+
|
|
2231
|
+
variable "subnet_ids" {
|
|
2232
|
+
description = "Subnet IDs to run the agent core runtime in. Required when enable_vpc is true."
|
|
2233
|
+
type = list(string)
|
|
2234
|
+
default = null
|
|
2235
|
+
}
|
|
2236
|
+
|
|
2237
|
+
variable "appconfig_application_id" {
|
|
2238
|
+
description = "ID of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_id\`). The agent reads its runtime configuration from this application."
|
|
2239
|
+
type = string
|
|
2240
|
+
}
|
|
2241
|
+
|
|
2242
|
+
variable "appconfig_application_arn" {
|
|
2243
|
+
description = "ARN of the shared runtime-config AppConfig application (from \`core/runtime-config/appconfig.application_arn\`). Used to scope the IAM read permission granted to the agent runtime."
|
|
2244
|
+
type = string
|
|
2245
|
+
}
|
|
2246
|
+
|
|
2247
|
+
module "agent_core_runtime" {
|
|
2248
|
+
source = "../../../core/agent-core"
|
|
2249
|
+
agent_runtime_name = "InMemoryTerraformAgent"
|
|
2250
|
+
docker_image_tag = "proj-in-memory-terraform-agent:latest"
|
|
2251
|
+
server_protocol = "HTTP"
|
|
2252
|
+
enable_vpc = var.enable_vpc
|
|
2253
|
+
vpc_id = var.vpc_id
|
|
2254
|
+
subnet_ids = var.subnet_ids
|
|
2255
|
+
|
|
2256
|
+
env = merge({
|
|
2257
|
+
RUNTIME_CONFIG_APP_ID = var.appconfig_application_id
|
|
2258
|
+
}, var.env)
|
|
2259
|
+
additional_iam_policy_statements = concat([
|
|
2260
|
+
{
|
|
2261
|
+
Effect = "Allow"
|
|
2262
|
+
Action = [
|
|
2263
|
+
"appconfig:StartConfigurationSession",
|
|
2264
|
+
"appconfig:GetLatestConfiguration"
|
|
2265
|
+
]
|
|
2266
|
+
Resource = ["\${var.appconfig_application_arn}/*"]
|
|
2267
|
+
},
|
|
2268
|
+
# Grant access for the agent to invoke bedrock models
|
|
2269
|
+
{
|
|
2270
|
+
Effect = "Allow"
|
|
2271
|
+
Action = [
|
|
2272
|
+
"bedrock:InvokeModel",
|
|
2273
|
+
"bedrock:InvokeModelWithResponseStream"
|
|
2274
|
+
]
|
|
2275
|
+
Resource = [
|
|
2276
|
+
"arn:aws:bedrock:*:*:foundation-model/*",
|
|
2277
|
+
"arn:aws:bedrock:*:*:inference-profile/*"
|
|
2278
|
+
]
|
|
2279
|
+
}
|
|
2280
|
+
], var.additional_iam_policy_statements)
|
|
2281
|
+
tags = var.tags
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
# Add agent runtime ARN to runtime config
|
|
2285
|
+
module "add_agent_runtime_to_runtime_config" {
|
|
2286
|
+
source = "../../../core/runtime-config/entry"
|
|
2287
|
+
|
|
2288
|
+
namespace = "agentcore"
|
|
2289
|
+
key = "agentRuntimes"
|
|
2290
|
+
value = { "InMemoryTerraformAgent" = { arn = module.agent_core_runtime.agent_core_runtime_arn } }
|
|
2291
|
+
|
|
2292
|
+
depends_on = [module.agent_core_runtime]
|
|
2293
|
+
}
|
|
2294
|
+
|
|
2295
|
+
output "agent_core_runtime_role_arn" {
|
|
2296
|
+
description = "ARN of the agent core runtime role"
|
|
2297
|
+
value = module.agent_core_runtime.agent_core_runtime_role_arn
|
|
2298
|
+
}
|
|
2299
|
+
|
|
2300
|
+
output "agent_core_runtime_arn" {
|
|
2301
|
+
description = "ARN of the Bedrock Agent Core runtime"
|
|
2302
|
+
value = module.agent_core_runtime.agent_core_runtime_arn
|
|
2303
|
+
}
|
|
2304
|
+
|
|
2305
|
+
output "invocation_url" {
|
|
2306
|
+
description = "HTTPS invocation URL of the runtime"
|
|
2307
|
+
value = module.agent_core_runtime.invocation_url
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
output "appconfig_application_id" {
|
|
2311
|
+
description = "AppConfig Application ID for runtime config (passthrough of the shared \`appconfig_application_id\` input)."
|
|
2312
|
+
value = var.appconfig_application_id
|
|
2313
|
+
}
|
|
2314
|
+
|
|
2315
|
+
output "security_group_id" {
|
|
2316
|
+
description = "Security group ID of the agent core runtime, for use in ingress rules on resources it must reach (e.g. a database). Null unless enable_vpc is true."
|
|
2317
|
+
value = module.agent_core_runtime.security_group_id
|
|
2318
|
+
}
|
|
2319
|
+
"
|
|
2320
|
+
`;
|
|
2321
|
+
|
|
2322
|
+
exports[`ts#agent generator > should not create session bucket infrastructure when session is in-memory > agent-construct.ts (in-memory) 1`] = `
|
|
2323
|
+
"import { Fn, Lazy, Names, Stack } from 'aws-cdk-lib';
|
|
2324
|
+
import { Platform } from 'aws-cdk-lib/aws-ecr-assets';
|
|
2325
|
+
import { Connections, IConnectable } from 'aws-cdk-lib/aws-ec2';
|
|
2326
|
+
import { Construct } from 'constructs';
|
|
2327
|
+
import * as path from 'path';
|
|
2328
|
+
import * as url from 'url';
|
|
2329
|
+
import {
|
|
2330
|
+
AgentRuntimeArtifact,
|
|
2331
|
+
ProtocolType,
|
|
2332
|
+
Runtime,
|
|
2333
|
+
RuntimeProps,
|
|
2334
|
+
} from 'aws-cdk-lib/aws-bedrockagentcore';
|
|
2335
|
+
import {
|
|
2336
|
+
PolicyStatement,
|
|
2337
|
+
IGrantable,
|
|
2338
|
+
IPrincipal,
|
|
2339
|
+
Grant,
|
|
2340
|
+
} from 'aws-cdk-lib/aws-iam';
|
|
2341
|
+
import { RuntimeConfig } from '../../../core/runtime-config.js';
|
|
2342
|
+
import { findWorkspaceRoot } from '../../../core/workspace.js';
|
|
2343
|
+
|
|
2344
|
+
export type InMemoryAgentProps = Omit<
|
|
2345
|
+
RuntimeProps,
|
|
2346
|
+
| 'runtimeName'
|
|
2347
|
+
| 'protocolConfiguration'
|
|
2348
|
+
| 'agentRuntimeArtifact'
|
|
2349
|
+
| 'authorizerConfiguration'
|
|
2350
|
+
>;
|
|
2351
|
+
|
|
2352
|
+
export class InMemoryAgent
|
|
2353
|
+
extends Construct
|
|
2354
|
+
implements IGrantable, IConnectable
|
|
2355
|
+
{
|
|
2356
|
+
public readonly dockerImage: AgentRuntimeArtifact;
|
|
2357
|
+
public readonly agentCoreRuntime: Runtime;
|
|
2358
|
+
|
|
2359
|
+
constructor(scope: Construct, id: string, props?: InMemoryAgentProps) {
|
|
2360
|
+
super(scope, id);
|
|
2361
|
+
|
|
2362
|
+
const rc = RuntimeConfig.ensure(this);
|
|
2363
|
+
|
|
2364
|
+
// Resolve the bundle output directory containing the Dockerfile and built artifacts
|
|
2365
|
+
const bundleDir = path.join(
|
|
2366
|
+
findWorkspaceRoot(url.fileURLToPath(new URL(import.meta.url))),
|
|
2367
|
+
'dist/apps/test-project/bundle/agent/in-memory-agent',
|
|
2368
|
+
);
|
|
2369
|
+
|
|
2370
|
+
this.dockerImage = AgentRuntimeArtifact.fromAsset(bundleDir, {
|
|
2371
|
+
platform: Platform.LINUX_ARM64,
|
|
2372
|
+
});
|
|
2373
|
+
|
|
2374
|
+
this.agentCoreRuntime = new Runtime(this, 'InMemoryAgent', {
|
|
2375
|
+
runtimeName: Lazy.string({
|
|
2376
|
+
produce: () =>
|
|
2377
|
+
Names.uniqueResourceName(this.agentCoreRuntime, { maxLength: 40 }),
|
|
2378
|
+
}),
|
|
2379
|
+
protocolConfiguration: ProtocolType.HTTP,
|
|
2380
|
+
agentRuntimeArtifact: this.dockerImage,
|
|
2381
|
+
...props,
|
|
2382
|
+
environmentVariables: {
|
|
2383
|
+
RUNTIME_CONFIG_APP_ID: rc.appConfigApplicationId,
|
|
2384
|
+
...props?.environmentVariables,
|
|
2385
|
+
},
|
|
2386
|
+
});
|
|
2387
|
+
|
|
2388
|
+
// Grant access for the agent to invoke bedrock models
|
|
2389
|
+
this.agentCoreRuntime.addToRolePolicy(
|
|
2390
|
+
new PolicyStatement({
|
|
2391
|
+
actions: [
|
|
2392
|
+
'bedrock:InvokeModel',
|
|
2393
|
+
'bedrock:InvokeModelWithResponseStream',
|
|
2394
|
+
],
|
|
2395
|
+
resources: [
|
|
2396
|
+
'arn:aws:bedrock:*:*:foundation-model/*',
|
|
2397
|
+
'arn:aws:bedrock:*:*:inference-profile/*',
|
|
2398
|
+
],
|
|
2399
|
+
}),
|
|
2400
|
+
);
|
|
2401
|
+
|
|
2402
|
+
rc.grantReadAppConfig(this.agentCoreRuntime);
|
|
2403
|
+
|
|
2404
|
+
rc.set('agentcore', 'agentRuntimes', {
|
|
2405
|
+
...rc.get('agentcore').agentRuntimes,
|
|
2406
|
+
InMemoryAgent: {
|
|
2407
|
+
arn: this.agentCoreRuntime.agentRuntimeArn,
|
|
2408
|
+
},
|
|
2409
|
+
});
|
|
2410
|
+
}
|
|
2411
|
+
|
|
2412
|
+
/**
|
|
2413
|
+
* The principal to grant permissions to.
|
|
2414
|
+
*/
|
|
2415
|
+
public get grantPrincipal(): IPrincipal {
|
|
2416
|
+
return this.agentCoreRuntime.grantPrincipal;
|
|
2417
|
+
}
|
|
2418
|
+
|
|
2419
|
+
/**
|
|
2420
|
+
* Network connections for this agent runtime.
|
|
2421
|
+
*/
|
|
2422
|
+
public get connections(): Connections {
|
|
2423
|
+
return this.agentCoreRuntime.connections;
|
|
2424
|
+
}
|
|
2425
|
+
|
|
2426
|
+
/**
|
|
2427
|
+
* The HTTPS invocation URL of the runtime.
|
|
2428
|
+
*/
|
|
2429
|
+
public get invocationUrl(): string {
|
|
2430
|
+
// The URL must URL-encode the runtime ARN (':' -> '%3A', '/' -> '%2F').
|
|
2431
|
+
// The ARN is a CDK token, so encode at deploy time via Fn.join/Fn.split.
|
|
2432
|
+
const encodedArn = Fn.join(
|
|
2433
|
+
'%2F',
|
|
2434
|
+
Fn.split(
|
|
2435
|
+
'/',
|
|
2436
|
+
Fn.join('%3A', Fn.split(':', this.agentCoreRuntime.agentRuntimeArn)),
|
|
2437
|
+
),
|
|
2438
|
+
);
|
|
2439
|
+
return \`https://bedrock-agentcore.\${Stack.of(this).region}.amazonaws.com/runtimes/\${encodedArn}/invocations?qualifier=DEFAULT\`;
|
|
2440
|
+
}
|
|
2441
|
+
|
|
2442
|
+
/**
|
|
2443
|
+
* Grants IAM permissions to invoke this agent runtime.
|
|
2444
|
+
*
|
|
2445
|
+
* @param grantee - The IAM principal to grant permissions to
|
|
2446
|
+
*/
|
|
2447
|
+
public grantInvokeAccess(grantee: IGrantable) {
|
|
2448
|
+
this.agentCoreRuntime.grantInvoke(grantee);
|
|
2449
|
+
|
|
2450
|
+
Grant.addToPrincipal({
|
|
2451
|
+
grantee,
|
|
2452
|
+
actions: ['bedrock-agentcore:InvokeAgentRuntimeWithWebSocketStream'],
|
|
2453
|
+
resourceArns: [
|
|
2454
|
+
this.agentCoreRuntime.agentRuntimeArn,
|
|
2455
|
+
\`\${this.agentCoreRuntime.agentRuntimeArn}/*\`,
|
|
2456
|
+
],
|
|
2457
|
+
});
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
"
|
|
2461
|
+
`;
|