@aws/agentcore 1.0.0-preview.2 → 1.0.0-preview.4

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.
Files changed (30) hide show
  1. package/dist/assets/__tests__/__snapshots__/assets.snapshot.test.ts.snap +29 -50
  2. package/dist/assets/__tests__/assets.snapshot.test.ts +10 -24
  3. package/dist/assets/cdk/bin/cdk.ts +4 -4
  4. package/dist/assets/cdk/lib/cdk-stack.ts +7 -43
  5. package/dist/assets/python/a2a/strands/capabilities/memory/session.py +6 -1
  6. package/dist/assets/python/agui/strands/capabilities/memory/session.py +6 -1
  7. package/dist/assets/python/http/strands/capabilities/memory/session.py +6 -1
  8. package/dist/cli/index.mjs +411 -392
  9. package/dist/lib/packaging/helpers.d.ts.map +1 -1
  10. package/dist/lib/packaging/helpers.js +6 -10
  11. package/dist/lib/packaging/helpers.js.map +1 -1
  12. package/dist/lib/schemas/io/config-io.d.ts.map +1 -1
  13. package/dist/lib/schemas/io/config-io.js.map +1 -1
  14. package/dist/schema/schemas/agent-env.d.ts +13 -0
  15. package/dist/schema/schemas/agent-env.d.ts.map +1 -1
  16. package/dist/schema/schemas/agent-env.js +20 -1
  17. package/dist/schema/schemas/agent-env.js.map +1 -1
  18. package/dist/schema/schemas/agentcore-project.d.ts +6 -0
  19. package/dist/schema/schemas/agentcore-project.d.ts.map +1 -1
  20. package/dist/schema/schemas/agentcore-project.js +1 -9
  21. package/dist/schema/schemas/agentcore-project.js.map +1 -1
  22. package/dist/schema/schemas/deployed-state.d.ts +26 -0
  23. package/dist/schema/schemas/deployed-state.d.ts.map +1 -1
  24. package/dist/schema/schemas/deployed-state.js +11 -1
  25. package/dist/schema/schemas/deployed-state.js.map +1 -1
  26. package/dist/schema/schemas/mcp.d.ts +2 -0
  27. package/dist/schema/schemas/mcp.d.ts.map +1 -1
  28. package/dist/schema/schemas/mcp.js +9 -1
  29. package/dist/schema/schemas/mcp.js.map +1 -1
  30. package/package.json +10 -5
@@ -110,8 +110,8 @@ async function main() {
110
110
  memoryName?: string;
111
111
  containerUri?: string;
112
112
  hasDockerfile?: boolean;
113
- dockerfileName?: string;
114
- harnessDir?: string;
113
+ dockerfile?: string;
114
+ codeLocation?: string;
115
115
  tools?: { type: string; name: string }[];
116
116
  apiKeyArn?: string;
117
117
  }[] = [];
@@ -126,8 +126,8 @@ async function main() {
126
126
  memoryName: harnessSpec.memory?.name,
127
127
  containerUri: harnessSpec.containerUri,
128
128
  hasDockerfile: !!harnessSpec.dockerfile,
129
- dockerfileName: harnessSpec.dockerfile,
130
- harnessDir,
129
+ dockerfile: harnessSpec.dockerfile,
130
+ codeLocation: harnessSpec.dockerfile ? harnessDir : undefined,
131
131
  tools: harnessSpec.tools,
132
132
  apiKeyArn: harnessSpec.model?.apiKeyArn,
133
133
  });
@@ -301,10 +301,6 @@ exports[`Assets Directory Snapshots > CDK assets > cdk/cdk/lib/cdk-stack.ts shou
301
301
  AgentCoreMcp,
302
302
  type AgentCoreProjectSpec,
303
303
  type AgentCoreMcpSpec,
304
- ContainerSourceAssetFromPath,
305
- AgentEcrRepository,
306
- ContainerBuildProject,
307
- ContainerImageBuilder,
308
304
  } from '@aws/agentcore-cdk';
309
305
  import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
310
306
  import { Construct } from 'constructs';
@@ -315,8 +311,8 @@ export interface HarnessConfig {
315
311
  memoryName?: string;
316
312
  containerUri?: string;
317
313
  hasDockerfile?: boolean;
318
- dockerfileName?: string;
319
- harnessDir?: string;
314
+ dockerfile?: string;
315
+ codeLocation?: string;
320
316
  tools?: { type: string; name: string }[];
321
317
  apiKeyArn?: string;
322
318
  }
@@ -336,6 +332,10 @@ export interface AgentCoreStackProps extends StackProps {
336
332
  credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
337
333
  /**
338
334
  * Harness role configurations. Each entry creates an IAM execution role for a harness.
335
+ *
336
+ * When \`hasDockerfile\` is true and \`codeLocation\` is provided (without an explicit
337
+ * \`containerUri\`), the L3 construct builds and pushes a container image via CodeBuild
338
+ * and emits its URI as a stack output for the post-CDK harness deployer.
339
339
  */
340
340
  harnesses?: HarnessConfig[];
341
341
  }
@@ -355,46 +355,10 @@ export class AgentCoreStack extends Stack {
355
355
 
356
356
  const { spec, mcpSpec, credentials, harnesses } = props;
357
357
 
358
- // Build container images for harnesses that specify a dockerfile (no containerUri).
359
- // Produces CDK outputs consumed by the imperative harness deployer.
360
- const harnessesForCdk = harnesses ? [...harnesses] : [];
361
- if (harnesses) {
362
- for (let i = 0; i < harnesses.length; i++) {
363
- const h = harnesses[i]!;
364
- if (h.hasDockerfile && !h.containerUri && h.harnessDir) {
365
- const pascalName = h.name.replace(/(^|_)([a-z])/g, (_: string, __: string, c: string) => c.toUpperCase());
366
- const sourceAsset = new ContainerSourceAssetFromPath(this, \`Harness\${pascalName}SourceAsset\`, {
367
- sourcePath: h.harnessDir,
368
- });
369
- const ecrRepo = new AgentEcrRepository(this, \`Harness\${pascalName}EcrRepo\`, {
370
- projectName: spec.name,
371
- agentName: \`harness-\${h.name}\`,
372
- });
373
- const buildProject = ContainerBuildProject.getOrCreate(this);
374
- buildProject.grantPushTo(ecrRepo.repository);
375
- sourceAsset.asset.grantRead(buildProject.role);
376
-
377
- const builder = new ContainerImageBuilder(this, \`Harness\${pascalName}ContainerBuild\`, {
378
- buildProject,
379
- sourceAsset,
380
- repository: ecrRepo,
381
- dockerfile: h.dockerfileName ?? 'Dockerfile',
382
- });
383
-
384
- new CfnOutput(this, \`Harness\${pascalName}ContainerUriOutput\`, {
385
- value: builder.containerUri,
386
- });
387
-
388
- // Pass the built containerUri to the harness role construct so it gets ECR pull permissions
389
- harnessesForCdk[i] = { ...h, containerUri: builder.containerUri };
390
- }
391
- }
392
- }
393
-
394
358
  // Create AgentCoreApplication with all agents and harness roles
395
359
  this.application = new AgentCoreApplication(this, 'Application', {
396
360
  spec,
397
- harnesses: harnessesForCdk.length > 0 ? harnessesForCdk : undefined,
361
+ harnesses: harnesses?.length ? harnesses : undefined,
398
362
  });
399
363
 
400
364
  // Create AgentCoreMcp if there are gateways configured
@@ -1987,6 +1951,7 @@ exports[`Assets Directory Snapshots > Python framework assets > python/python/a2
1987
1951
 
1988
1952
  exports[`Assets Directory Snapshots > Python framework assets > python/python/a2a/strands/capabilities/memory/session.py should match snapshot 1`] = `
1989
1953
  "import os
1954
+ import uuid
1990
1955
  from typing import Optional
1991
1956
 
1992
1957
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -1995,10 +1960,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
1995
1960
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
1996
1961
  REGION = os.getenv("AWS_REGION")
1997
1962
 
1998
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
1963
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
1999
1964
  if not MEMORY_ID:
2000
1965
  return None
2001
1966
 
1967
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
1968
+ # without a runtime session header, so synthesize one when absent.
1969
+ session_id = session_id or uuid.uuid4().hex
1970
+
2002
1971
  {{#if memoryProviders.[0].strategies.length}}
2003
1972
  retrieval_config = {
2004
1973
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -2822,6 +2791,7 @@ exports[`Assets Directory Snapshots > Python framework assets > python/python/ag
2822
2791
 
2823
2792
  exports[`Assets Directory Snapshots > Python framework assets > python/python/agui/strands/capabilities/memory/session.py should match snapshot 1`] = `
2824
2793
  "import os
2794
+ import uuid
2825
2795
  from typing import Optional
2826
2796
 
2827
2797
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -2830,10 +2800,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
2830
2800
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
2831
2801
  REGION = os.getenv("AWS_REGION")
2832
2802
 
2833
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
2803
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
2834
2804
  if not MEMORY_ID:
2835
2805
  return None
2836
2806
 
2807
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
2808
+ # without a runtime session header, so synthesize one when absent.
2809
+ session_id = session_id or uuid.uuid4().hex
2810
+
2837
2811
  {{#if memoryProviders.[0].strategies.length}}
2838
2812
  retrieval_config = {
2839
2813
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -5091,6 +5065,7 @@ exports[`Assets Directory Snapshots > Python framework assets > python/python/ht
5091
5065
 
5092
5066
  exports[`Assets Directory Snapshots > Python framework assets > python/python/http/strands/capabilities/memory/session.py should match snapshot 1`] = `
5093
5067
  "import os
5068
+ import uuid
5094
5069
  from typing import Optional
5095
5070
 
5096
5071
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -5099,10 +5074,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
5099
5074
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
5100
5075
  REGION = os.getenv("AWS_REGION")
5101
5076
 
5102
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
5077
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
5103
5078
  if not MEMORY_ID:
5104
5079
  return None
5105
5080
 
5081
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
5082
+ # without a runtime session header, so synthesize one when absent.
5083
+ session_id = session_id or uuid.uuid4().hex
5084
+
5106
5085
  {{#if memoryProviders.[0].strategies.length}}
5107
5086
  retrieval_config = {
5108
5087
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -87,36 +87,22 @@ describe('Assets Directory Snapshots', () => {
87
87
  });
88
88
  });
89
89
 
90
- describe('Static assets', () => {
90
+ describe.skipIf(assetFiles.filter(f => f.startsWith('static/')).length === 0)('Static assets', () => {
91
91
  const staticFiles = assetFiles.filter(f => f.startsWith('static/'));
92
92
 
93
- if (staticFiles.length > 0) {
94
- it.each(staticFiles)('static/%s should match snapshot', file => {
95
- const content = readFileContent(path.join(ASSETS_DIR, file));
96
- expect(content).toMatchSnapshot();
97
- });
98
- } else {
99
- it('static directory is empty or does not exist', () => {
100
- // Static assets may not exist
101
- expect(true).toBe(true);
102
- });
103
- }
93
+ it.each(staticFiles)('static/%s should match snapshot', file => {
94
+ const content = readFileContent(path.join(ASSETS_DIR, file));
95
+ expect(content).toMatchSnapshot();
96
+ });
104
97
  });
105
98
 
106
- describe('TypeScript assets', () => {
99
+ describe.skipIf(assetFiles.filter(f => f.startsWith('typescript/')).length === 0)('TypeScript assets', () => {
107
100
  const tsFiles = assetFiles.filter(f => f.startsWith('typescript/'));
108
101
 
109
- if (tsFiles.length > 0) {
110
- it.each(tsFiles)('typescript/%s should match snapshot', file => {
111
- const content = readFileContent(path.join(ASSETS_DIR, file));
112
- expect(content).toMatchSnapshot();
113
- });
114
- } else {
115
- it('typescript directory is empty or contains only placeholder files', () => {
116
- // TypeScript assets may not exist yet
117
- expect(true).toBe(true);
118
- });
119
- }
102
+ it.each(tsFiles)('typescript/%s should match snapshot', file => {
103
+ const content = readFileContent(path.join(ASSETS_DIR, file));
104
+ expect(content).toMatchSnapshot();
105
+ });
120
106
  });
121
107
 
122
108
  describe('Root-level assets', () => {
@@ -65,8 +65,8 @@ async function main() {
65
65
  memoryName?: string;
66
66
  containerUri?: string;
67
67
  hasDockerfile?: boolean;
68
- dockerfileName?: string;
69
- harnessDir?: string;
68
+ dockerfile?: string;
69
+ codeLocation?: string;
70
70
  tools?: { type: string; name: string }[];
71
71
  apiKeyArn?: string;
72
72
  }[] = [];
@@ -81,8 +81,8 @@ async function main() {
81
81
  memoryName: harnessSpec.memory?.name,
82
82
  containerUri: harnessSpec.containerUri,
83
83
  hasDockerfile: !!harnessSpec.dockerfile,
84
- dockerfileName: harnessSpec.dockerfile,
85
- harnessDir,
84
+ dockerfile: harnessSpec.dockerfile,
85
+ codeLocation: harnessSpec.dockerfile ? harnessDir : undefined,
86
86
  tools: harnessSpec.tools,
87
87
  apiKeyArn: harnessSpec.model?.apiKeyArn,
88
88
  });
@@ -3,10 +3,6 @@ import {
3
3
  AgentCoreMcp,
4
4
  type AgentCoreProjectSpec,
5
5
  type AgentCoreMcpSpec,
6
- ContainerSourceAssetFromPath,
7
- AgentEcrRepository,
8
- ContainerBuildProject,
9
- ContainerImageBuilder,
10
6
  } from '@aws/agentcore-cdk';
11
7
  import { CfnOutput, Stack, type StackProps } from 'aws-cdk-lib';
12
8
  import { Construct } from 'constructs';
@@ -17,8 +13,8 @@ export interface HarnessConfig {
17
13
  memoryName?: string;
18
14
  containerUri?: string;
19
15
  hasDockerfile?: boolean;
20
- dockerfileName?: string;
21
- harnessDir?: string;
16
+ dockerfile?: string;
17
+ codeLocation?: string;
22
18
  tools?: { type: string; name: string }[];
23
19
  apiKeyArn?: string;
24
20
  }
@@ -38,6 +34,10 @@ export interface AgentCoreStackProps extends StackProps {
38
34
  credentials?: Record<string, { credentialProviderArn: string; clientSecretArn?: string }>;
39
35
  /**
40
36
  * Harness role configurations. Each entry creates an IAM execution role for a harness.
37
+ *
38
+ * When `hasDockerfile` is true and `codeLocation` is provided (without an explicit
39
+ * `containerUri`), the L3 construct builds and pushes a container image via CodeBuild
40
+ * and emits its URI as a stack output for the post-CDK harness deployer.
41
41
  */
42
42
  harnesses?: HarnessConfig[];
43
43
  }
@@ -57,46 +57,10 @@ export class AgentCoreStack extends Stack {
57
57
 
58
58
  const { spec, mcpSpec, credentials, harnesses } = props;
59
59
 
60
- // Build container images for harnesses that specify a dockerfile (no containerUri).
61
- // Produces CDK outputs consumed by the imperative harness deployer.
62
- const harnessesForCdk = harnesses ? [...harnesses] : [];
63
- if (harnesses) {
64
- for (let i = 0; i < harnesses.length; i++) {
65
- const h = harnesses[i]!;
66
- if (h.hasDockerfile && !h.containerUri && h.harnessDir) {
67
- const pascalName = h.name.replace(/(^|_)([a-z])/g, (_: string, __: string, c: string) => c.toUpperCase());
68
- const sourceAsset = new ContainerSourceAssetFromPath(this, `Harness${pascalName}SourceAsset`, {
69
- sourcePath: h.harnessDir,
70
- });
71
- const ecrRepo = new AgentEcrRepository(this, `Harness${pascalName}EcrRepo`, {
72
- projectName: spec.name,
73
- agentName: `harness-${h.name}`,
74
- });
75
- const buildProject = ContainerBuildProject.getOrCreate(this);
76
- buildProject.grantPushTo(ecrRepo.repository);
77
- sourceAsset.asset.grantRead(buildProject.role);
78
-
79
- const builder = new ContainerImageBuilder(this, `Harness${pascalName}ContainerBuild`, {
80
- buildProject,
81
- sourceAsset,
82
- repository: ecrRepo,
83
- dockerfile: h.dockerfileName ?? 'Dockerfile',
84
- });
85
-
86
- new CfnOutput(this, `Harness${pascalName}ContainerUriOutput`, {
87
- value: builder.containerUri,
88
- });
89
-
90
- // Pass the built containerUri to the harness role construct so it gets ECR pull permissions
91
- harnessesForCdk[i] = { ...h, containerUri: builder.containerUri };
92
- }
93
- }
94
- }
95
-
96
60
  // Create AgentCoreApplication with all agents and harness roles
97
61
  this.application = new AgentCoreApplication(this, 'Application', {
98
62
  spec,
99
- harnesses: harnessesForCdk.length > 0 ? harnessesForCdk : undefined,
63
+ harnesses: harnesses?.length ? harnesses : undefined,
100
64
  });
101
65
 
102
66
  // Create AgentCoreMcp if there are gateways configured
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import uuid
2
3
  from typing import Optional
3
4
 
4
5
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -7,10 +8,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
7
8
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
8
9
  REGION = os.getenv("AWS_REGION")
9
10
 
10
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
11
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
11
12
  if not MEMORY_ID:
12
13
  return None
13
14
 
15
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
16
+ # without a runtime session header, so synthesize one when absent.
17
+ session_id = session_id or uuid.uuid4().hex
18
+
14
19
  {{#if memoryProviders.[0].strategies.length}}
15
20
  retrieval_config = {
16
21
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import uuid
2
3
  from typing import Optional
3
4
 
4
5
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -7,10 +8,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
7
8
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
8
9
  REGION = os.getenv("AWS_REGION")
9
10
 
10
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
11
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
11
12
  if not MEMORY_ID:
12
13
  return None
13
14
 
15
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
16
+ # without a runtime session header, so synthesize one when absent.
17
+ session_id = session_id or uuid.uuid4().hex
18
+
14
19
  {{#if memoryProviders.[0].strategies.length}}
15
20
  retrieval_config = {
16
21
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}
@@ -1,4 +1,5 @@
1
1
  import os
2
+ import uuid
2
3
  from typing import Optional
3
4
 
4
5
  from bedrock_agentcore.memory.integrations.strands.config import AgentCoreMemoryConfig{{#if memoryProviders.[0].strategies.length}}, RetrievalConfig{{/if}}
@@ -7,10 +8,14 @@ from bedrock_agentcore.memory.integrations.strands.session_manager import AgentC
7
8
  MEMORY_ID = os.getenv("{{memoryProviders.[0].envVarName}}")
8
9
  REGION = os.getenv("AWS_REGION")
9
10
 
10
- def get_memory_session_manager(session_id: str, actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
11
+ def get_memory_session_manager(session_id: Optional[str], actor_id: str) -> Optional[AgentCoreMemorySessionManager]:
11
12
  if not MEMORY_ID:
12
13
  return None
13
14
 
15
+ # AgentCoreMemoryConfig rejects None; OAuth/CUSTOM_JWT callers can reach us
16
+ # without a runtime session header, so synthesize one when absent.
17
+ session_id = session_id or uuid.uuid4().hex
18
+
14
19
  {{#if memoryProviders.[0].strategies.length}}
15
20
  retrieval_config = {
16
21
  {{#if (includes memoryProviders.[0].strategies "SEMANTIC")}}