@aws/agentcore 1.0.0-rc.1 → 1.0.0-rc.3

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 (37) hide show
  1. package/README.md +251 -11
  2. package/dist/assets/cdk/README.md +42 -19
  3. package/dist/assets/cdk/bin/cdk.ts +22 -173
  4. package/dist/assets/cdk/lib/cdk-stack.ts +18 -80
  5. package/dist/assets/cdk/package.json +3 -10
  6. package/dist/assets/cdk/tsconfig.json +1 -1
  7. package/dist/assets/evaluators/python-lambda/README.md +5 -1
  8. package/dist/assets/templates/a2a-python-strands/pyproject.toml +1 -1
  9. package/dist/assets/templates/agent-python-langchain/README.md +4 -3
  10. package/dist/assets/templates/agent-python-langchain/main.py +7 -11
  11. package/dist/assets/templates/agent-python-strands/README.md +16 -2
  12. package/dist/assets/templates/agent-python-strands/main.py +40 -81
  13. package/dist/assets/templates/agent-python-strands/memory/session.py +1 -5
  14. package/dist/assets/templates/agent-python-strands/model/load.py +4 -4
  15. package/dist/assets/templates/agent-python-strands/parse.py +41 -0
  16. package/dist/assets/templates/agent-typescript-strands/README.md +23 -2
  17. package/dist/assets/templates/agent-typescript-strands/main.ts +4 -13
  18. package/dist/assets/templates/agent-typescript-strands/memory/memory.ts +1 -12
  19. package/dist/assets/templates/agent-typescript-strands/package.json.template +0 -1
  20. package/dist/assets/templates/agui-python-strands/pyproject.toml +1 -1
  21. package/dist/assets/templates/export-harness-python/model/load.py +3 -3
  22. package/dist/assets/templates/harness/harness.yaml +157 -0
  23. package/dist/main.js +524 -132
  24. package/package.json +6 -4
  25. package/dist/assets/cdk/.prettierrc +0 -8
  26. package/dist/assets/cdk/jest.config.js +0 -9
  27. package/dist/assets/cdk/npmignore.template +0 -6
  28. package/dist/assets/cdk/test/cdk.test.ts +0 -120
  29. package/dist/assets/evaluators/autoevals-lambda/README.md +0 -23
  30. package/dist/assets/evaluators/autoevals-lambda/execution-role-policy.json +0 -15
  31. package/dist/assets/evaluators/autoevals-lambda/lambda_function.py +0 -37
  32. package/dist/assets/evaluators/autoevals-lambda/pyproject.toml +0 -23
  33. package/dist/assets/evaluators/deepeval-lambda/README.md +0 -23
  34. package/dist/assets/evaluators/deepeval-lambda/execution-role-policy.json +0 -15
  35. package/dist/assets/evaluators/deepeval-lambda/lambda_function.py +0 -29
  36. package/dist/assets/evaluators/deepeval-lambda/pyproject.toml +0 -22
  37. package/dist/assets/templates/agent-typescript-strands/mcp_client/client.ts +0 -11
package/README.md CHANGED
@@ -62,12 +62,15 @@ agentcore # interactive TUI
62
62
  │ │ ├── list # list API key credential providers
63
63
  │ │ ├── update # update an API key credential provider
64
64
  │ │ └── delete # delete an API key credential provider
65
- │ └── oauth2-credential-provider
66
- │ ├── create # create an OAuth2 credential provider
67
- │ ├── get # get an OAuth2 credential provider
68
- │ ├── list # list OAuth2 credential providers
69
- │ ├── update # update an OAuth2 credential provider
70
- │ └── delete # delete an OAuth2 credential provider
65
+ │ ├── oauth2-credential-provider
66
+ │ │ ├── create # create an OAuth2 credential provider
67
+ │ │ ├── get # get an OAuth2 credential provider
68
+ │ │ ├── list # list OAuth2 credential providers
69
+ │ │ ├── update # update an OAuth2 credential provider
70
+ │ │ └── delete # delete an OAuth2 credential provider
71
+ │ └── payment-credential-provider
72
+ │ ├── get # get a payment credential provider
73
+ │ └── list # list payment credential providers
71
74
  ├── runtime # inspect deployed AgentCore Runtimes
72
75
  │ ├── get # fetch a Runtime by id
73
76
  │ ├── list # list Runtimes (server-side paginated)
@@ -107,6 +110,20 @@ agentcore # interactive TUI
107
110
  │ │ └── list # list Rules under a Gateway
108
111
  │ └── policy
109
112
  │ └── generate # generate Cedar for a Gateway from a prompt (TUI when run bare)
113
+ ├── payment # inspect AgentCore Payments (command line only for now)
114
+ │ ├── manager
115
+ │ │ ├── get # get a payment manager by id
116
+ │ │ └── list # list payment managers (server-side paginated)
117
+ │ ├── connector # connectors under a payment manager
118
+ │ │ ├── get # get a connector (shows the Quick Create authorization URL while pending)
119
+ │ │ └── list # list a manager's connectors
120
+ │ ├── session # budget-limited payment contexts (data plane)
121
+ │ │ ├── get
122
+ │ │ └── list
123
+ │ └── instrument # embedded crypto wallets (data plane)
124
+ │ ├── get
125
+ │ ├── list
126
+ │ └── balance # read token balance on an explicit chain (default token: USDC)
110
127
  ├── eval # evaluate and optimize AgentCore agents
111
128
  │ └── evaluator # manage AgentCore evaluators
112
129
  │ ├── llm-as-a-judge # LLM-as-a-Judge evaluators
@@ -121,7 +138,9 @@ agentcore # interactive TUI
121
138
  ├── project # manage an AgentCore project (scaffold → deploy)
122
139
  │ ├── create # create a project: a managed harness by default,
123
140
  │ │ # or scaffolded runtime code via --template;
124
- │ │ # bare `project create` opens an interactive wizard
141
+ │ │ # bare `project create` opens an interactive wizard.
142
+ │ │ # agentcore/cdk/ holds a two-file CDK app on
143
+ │ │ # @aws/agentcore-cdk (bin/cdk.ts, lib/cdk-stack.ts)
125
144
  │ ├── add # add a resource to the project (runtime, harness, memory, …)
126
145
  │ ├── export
127
146
  │ │ └── harness # convert a harness into an editable Strands runtime agent
@@ -139,7 +158,11 @@ agentcore # interactive TUI
139
158
  │ │ ├── runtime # use the existing Runtime invoke experience
140
159
  │ │ └── harness # use the existing Harness invoke experience
141
160
  │ ├── status # inspect deployed project resources (TUI when run bare)
142
- │ └── build # synthesize the project's CloudFormation templates
161
+ │ ├── build # synthesize the project's CloudFormation templates
162
+ │ ├── log
163
+ │ │ └── runtime # resolve a project Runtime and inspect its logs
164
+ │ └── traces
165
+ │ └── runtime
143
166
  └── config # read/write global config values
144
167
  ```
145
168
 
@@ -157,6 +180,60 @@ pre-built container image or a custom Dockerfile, that is reported in
157
180
  `EXPORT_NOTES.md` rather than rebuilt. Path-based skills are not supported,
158
181
  since the exported agent has no container filesystem to read them from.
159
182
 
183
+ ### Harness Project Files
184
+
185
+ `project create` (without `--template`) and `project add harness` share the same
186
+ scaffolding flow. Each harness has `app/<name>/harness.yaml` and
187
+ `app/<name>/system-prompt.md`. YAML is the harness configuration format.
188
+ The YAML contains the supplied settings and
189
+ commented optional examples. Tools are opt-in. Newly scaffolded harnesses
190
+ explicitly use `memory: { mode: managed }` unless another memory configuration
191
+ was supplied. Reading an existing file with no `memory` setting still means
192
+ disabled memory; reading never adds the scaffold default.
193
+
194
+ ```yaml
195
+ name: assistant
196
+ model:
197
+ provider: bedrock
198
+ modelId: global.anthropic.claude-sonnet-4-6
199
+ # Instructions come from system-prompt.md unless systemPrompt is set inline.
200
+ # systemPrompt: You are a helpful assistant.
201
+ memory:
202
+ mode: managed
203
+ ```
204
+
205
+ Both deployment and local export use inline `systemPrompt` text when it is
206
+ provided. Otherwise, instructions come from `system-prompt.md` next to
207
+ `harness.yaml`. Prompt contents are not trimmed, and blank prompts are rejected.
208
+ Prompt settings do not resolve local file references.
209
+
210
+ ```yaml
211
+ systemPrompt: |
212
+ You are a concise assistant.
213
+ truncation:
214
+ strategy: summarization
215
+ config:
216
+ summarization:
217
+ summarizationSystemPrompt: Keep decisions and open questions.
218
+ ```
219
+
220
+ `project add harness --system-prompt "Your instructions"` writes the supplied
221
+ text to `system-prompt.md`, leaving `systemPrompt` out of the generated YAML.
222
+ Summary instructions in
223
+ `truncation.config.summarization.summarizationSystemPrompt` are inline text.
224
+
225
+ Skills are unchanged: skill paths refer to the **runtime/container filesystem**,
226
+ not local files to package. Other fields do not support local includes.
227
+ Malformed YAML, duplicate keys, and existing schema violations fail the read.
228
+ Unknown fields at the harness root and directly inside `model` are stripped
229
+ from the parsed configuration. Nested configurations keep their existing
230
+ validation contracts. Free-form
231
+ maps such as headers, tags, environment variables, `additionalParams`, and
232
+ `inputSchema` still accept arbitrary keys.
233
+ Build, deploy, and export do not rewrite harness YAML or remove its comments.
234
+ `agentcore.json`, deployment targets, JSON CLI flags/output, and service payloads
235
+ are unchanged.
236
+
160
237
  Global flags (declared at the root, available on every command):
161
238
 
162
239
  | Flag | Purpose |
@@ -186,6 +263,111 @@ agentcore project invoke harness \
186
263
  Use `--target` to select a deployment target. When a project declares exactly
187
264
  one resource of the requested type, `--name` may be omitted.
188
265
 
266
+ ### Inspect project logs
267
+
268
+ Project logging resolves a logical resource name through the selected
269
+ deployment target, so physical IDs and deployment regions do not need to be
270
+ supplied:
271
+
272
+ ```bash
273
+ agentcore project log runtime
274
+ agentcore project log runtime --name checkout --target production
275
+ agentcore project log runtime --name checkout --since 1h --level error
276
+ agentcore project log harness
277
+ agentcore project log harness --name support --target production
278
+ agentcore project log harness --name support --since 1h --level error
279
+ ```
280
+
281
+ When the project declares exactly one resource of the requested type, `--name`
282
+ may be omitted. For Harnesses, the CLI also resolves the managed Harness to its
283
+ underlying Runtime before reading CloudWatch. Use the imperative
284
+ `agentcore runtime logs` or `agentcore harness logs` commands when addressing a
285
+ physical resource directly or working outside a project.
286
+
287
+ ### Inspect project traces
288
+
289
+ Project tracing uses the same logical resource and deployment target
290
+ resolution, then lists or downloads traces from the resolved Runtime's
291
+ deployment region:
292
+
293
+ ```bash
294
+ agentcore project traces runtime list
295
+ agentcore project traces runtime list --name checkout --target production --since 30m
296
+ agentcore project traces runtime get <traceId> --name checkout --output trace.json
297
+ agentcore project traces harness list
298
+ agentcore project traces harness list --name support --target production --since 30m
299
+ agentcore project traces harness get <traceId> --name support --output trace.json
300
+ ```
301
+
302
+ When the project declares exactly one resource of the requested type, `--name`
303
+ may be omitted. For Harnesses, the CLI resolves the underlying Runtime before
304
+ querying its traces. Use the imperative `agentcore runtime traces` or
305
+ `agentcore harness traces` commands when addressing a physical resource
306
+ directly or working outside a project.
307
+
308
+ ### Inspect AgentCore Payments
309
+
310
+ The `payment` commands call the Payments control and data planes directly, with
311
+ no project involved. This command family currently provides read-only inspection
312
+ of existing managers, connectors, sessions, instruments, and payment credential
313
+ providers. It does not create IAM roles or change provider credentials.
314
+
315
+ Choose a manager from `manager list` and use its `paymentManagerId` below:
316
+
317
+ ```bash
318
+ agentcore payment manager list --json
319
+ MANAGER_ID='<paymentManagerId from manager list>'
320
+ agentcore payment manager get --id "$MANAGER_ID"
321
+ agentcore payment connector list --manager-id "$MANAGER_ID"
322
+ ```
323
+
324
+ `--user-id` is the application user ID used when the session or instrument was
325
+ created, not an IAM username or AWS profile. Session and instrument reads require
326
+ it with IAM authentication; their lists return that user's resources, not every
327
+ user's resources under the manager.
328
+
329
+ ```bash
330
+ USER_ID='alice' # Use the application user ID associated with the resources.
331
+ agentcore payment session list --manager-id "$MANAGER_ID" --user-id "$USER_ID"
332
+ agentcore payment instrument list --manager-id "$MANAGER_ID" --user-id "$USER_ID"
333
+
334
+ # Use paymentInstrumentId and paymentConnectorId from the same instrument list item.
335
+ INSTRUMENT_ID='<paymentInstrumentId>'
336
+ CONNECTOR_ID='<paymentConnectorId>'
337
+ agentcore payment instrument get --manager-id "$MANAGER_ID" \
338
+ --instrument-id "$INSTRUMENT_ID" --user-id "$USER_ID"
339
+ agentcore payment instrument balance --manager-id "$MANAGER_ID" \
340
+ --connector-id "$CONNECTOR_ID" --instrument-id "$INSTRUMENT_ID" \
341
+ --user-id "$USER_ID" --chain BASE_SEPOLIA
342
+ ```
343
+
344
+ To inspect connector or credential provider metadata:
345
+
346
+ ```bash
347
+ agentcore payment connector get --manager-id "$MANAGER_ID" --connector-id "$CONNECTOR_ID"
348
+ agentcore identity payment-credential-provider list --json
349
+ agentcore identity payment-credential-provider get --name '<provider name>'
350
+ ```
351
+
352
+ The optional `--agent-name` on session and instrument reads labels the request for
353
+ observability. It does not select an AgentCore agent or filter the results.
354
+
355
+ `instrument get` returns instrument metadata without querying balances. `balance`
356
+ requires an explicit chain and defaults to `--token USDC`; wallet network families
357
+ such as ETHEREUM do not identify whether to query mainnet or a testnet. The JSON
358
+ response retains the raw atomic amount string and decimals. A service error is
359
+ reported as an error, never converted to a zero balance.
360
+
361
+ Data-plane commands work against managers that use the `AWS_IAM` authorizer.
362
+ The CLI resolves `--manager-id` through `GetPaymentManager` in the configured
363
+ region, then supplies the returned ARN to the data-plane API. Callers need
364
+ `bedrock-agentcore:GetPaymentManager` as well as the relevant data-plane action.
365
+ Region resolution follows the other imperative commands: `--region`, environment
366
+ variables, the active AWS profile, then the CLI default.
367
+ A `CUSTOM_JWT` manager accepts only bearer tokens on its data plane, which
368
+ these commands do not send yet; the CLI reports that limitation before calling
369
+ the data plane.
370
+
189
371
  ### Examples
190
372
 
191
373
  ```bash
@@ -251,7 +433,7 @@ agentcore runtime version list --id <runtimeId> --max-results 20
251
433
  agentcore runtime endpoint get --id <runtimeId> --qualifier DEFAULT
252
434
  agentcore runtime endpoint list --id <runtimeId> --max-results 20
253
435
 
254
- # Follow a Runtime's logs live (Ctrl+C to stop); inside a project --id is optional
436
+ # Follow a Runtime's logs live by resource ID (Ctrl+C to stop)
255
437
  agentcore runtime logs --id <runtimeId>
256
438
  agentcore runtime logs --id <runtimeId> --level error --query "database"
257
439
 
@@ -263,6 +445,13 @@ agentcore runtime logs --id <runtimeId> --since 2026-08-30T12:00:00Z --until now
263
445
  agentcore runtime traces list --id <runtimeId> --since 30m
264
446
  agentcore runtime traces get <traceId> --id <runtimeId> --output trace.json
265
447
 
448
+ # Resolve project resources by logical name and deployment target
449
+ agentcore project log harness --name support --target production --since 1h
450
+ agentcore project traces runtime list --name checkout --target production --since 30m
451
+ agentcore project traces runtime get <traceId> --name checkout --output trace.json
452
+ agentcore project traces harness list --name support --target production --since 30m
453
+ agentcore project traces harness get <traceId> --name support --output trace.json
454
+
266
455
  # Inspect AgentCore Memories without project configuration or deployment
267
456
  agentcore memory get --id <memoryId>
268
457
  agentcore memory get --id <memoryId> --view without_decryption
@@ -342,6 +531,55 @@ Source-aware values: any field flag documented as such accepts the value inline,
342
531
  `file://` convention). A command reads stdin from at most one flag. For example,
343
532
  `--instructions file://order-quality.txt` or `--instructions -`.
344
533
 
534
+ Project credentials: a `credentials[]` entry in `agentcore.json` is named by its
535
+ spec name and keeps its secret in `agentcore/.env.local` under
536
+ `AGENTCORE_CREDENTIAL_<NAME>` (with a field suffix for OAuth2 and payment
537
+ values). `project deploy` provisions the Identity credential provider before
538
+ synth under the name `<project>_<target>_<credential>`, so two targets in one
539
+ account and region get separate providers, and records its ARN in
540
+ `deployed-state.json` under the spec name. A credential removed from the spec
541
+ has its provider deleted on the next deploy of each target, after the stack
542
+ update. Tearing a target down (deploying a spec with nothing left to deploy,
543
+ which is where `project remove all` leads) deletes every provider the target
544
+ owns: API key, OAuth2 and payment. CLI versions before this change named providers by the bare credential name. Those
545
+ providers stay in the account after an upgrade, untouched by deploys and
546
+ teardowns. Delete them with `agentcore identity api-key-credential-provider
547
+ delete --name <credential>`, the `oauth2-credential-provider` equivalent, or
548
+ `aws bedrock-agentcore-control delete-payment-credential-provider` once nothing
549
+ else uses them.
550
+
551
+ ### Extending the CDK app
552
+
553
+ `agentcore/cdk/` is a CDK app of two files. `bin/cdk.ts` reads the project once
554
+ (`readAgentCoreProject`), makes one stack per deployment target
555
+ (`resolveTargetStacks`) and turns `agentcore.json` into the application's props
556
+ (`transformAgentCoreJson`) — all three come from `@aws/agentcore-cdk`, so how
557
+ `agentcore.json` is interpreted changes with the library version, not with code
558
+ on your disk. `lib/cdk-stack.ts` instantiates one `AgentCoreApplication`; it is
559
+ the file you edit. Add your own resources after the application and wire them to
560
+ a runtime or harness through the application's accessors: runtimes and harnesses
561
+ implement `iam.IGrantable`, so any AWS L2 grant accepts them, and they expose
562
+ `grantRead` / `grantWrite` / `grantReadWrite` (DynamoDB tables, S3 buckets,
563
+ Secrets Manager secrets) and `addEnvironmentVariable`:
564
+
565
+ ```ts
566
+ import * as dynamodb from "aws-cdk-lib/aws-dynamodb";
567
+
568
+ const orders = new dynamodb.Table(this, "Orders", {
569
+ partitionKey: { name: "pk", type: dynamodb.AttributeType.STRING },
570
+ });
571
+ const checkout = this.application.runtime("checkout"); // or this.application.harness('support')
572
+ checkout.grantReadWrite(orders);
573
+ checkout.addEnvironmentVariable("ORDERS_TABLE", orders.tableName);
574
+ orders.grantReadData(this.application.harness("support")); // any AWS L2 grant works too
575
+ ```
576
+
577
+ Redeploy with `agentcore project deploy`. An unknown name fails at synth and lists
578
+ the names that exist; a runtime or harness configured with an `executionRoleArn`
579
+ warns at synth about every grant CDK could not attach to the imported role. Note
580
+ that `agentcore project status` reports only the resources `agentcore.json`
581
+ declares, not the ones you add in the stack.
582
+
345
583
  ### Invoke a Gateway
346
584
 
347
585
  Gateway Invoke is a project-independent HTTP request command with headless and
@@ -967,8 +1205,10 @@ npm i -g ./aws-agentcore-0.28.1.tgz
967
1205
  output while text is selected (the title bar shows `Select`). Press `Esc`.
968
1206
  Windows Terminal does not do this.
969
1207
  - **`project create` refuses a long path**: Windows caps paths at 260 characters
970
- unless `LongPathsEnabled` is set, and the CDK app's `node_modules` needs about
971
- 100 of them. Create the project higher in the tree or enable long paths.
1208
+ unless `LongPathsEnabled` is set, and the CDK app's `node_modules` puts its
1209
+ deepest file 155 characters below the project root (aws-cdk-lib's own shipped
1210
+ fixtures), so the project root must be at most 104 characters. Create the
1211
+ project higher in the tree or enable long paths.
972
1212
 
973
1213
  # Build
974
1214
 
@@ -1,29 +1,52 @@
1
- # AgentCore CDK Project
1
+ # AgentCore CDK app
2
2
 
3
- This CDK project is managed by the AgentCore CLI. It deploys your agent infrastructure into AWS using the `@aws/agentcore-cdk` L3 constructs.
3
+ This CDK app is managed by the AgentCore CLI. It deploys everything declared in `agentcore/agentcore.json` into AWS
4
+ through the `@aws/agentcore-cdk` constructs. It is two files:
4
5
 
5
- ## Structure
6
+ - `bin/cdk.ts` — the entry point. It reads the project once (`readAgentCoreProject`), creates one stack per deployment
7
+ target (`resolveTargetStacks`), and turns `agentcore.json` into the application's props (`transformAgentCoreJson`).
8
+ Everything about how `agentcore.json` is interpreted lives in the library, so it changes with the library version, not
9
+ with this file.
10
+ - `lib/cdk-stack.ts` — `AgentCoreStack`, which instantiates one `AgentCoreApplication`. This is the file you edit.
6
11
 
7
- - `bin/cdk.ts` — Entry point. Reads project configuration from `agentcore/` and creates a stack per deployment target.
8
- - `lib/cdk-stack.ts` — Defines `AgentCoreStack`, which wraps the `AgentCoreApplication` L3 construct.
9
- - `test/cdk.test.ts` — Unit tests for stack synthesis.
12
+ Harness settings are read from `harness.yaml`. Inline `systemPrompt` text overrides
13
+ the conventional `system-prompt.md` file in the harness directory.
10
14
 
11
- ## Useful commands
15
+ ## The CLI runs it for you
12
16
 
13
- - `npm run build` compile TypeScript to JavaScript
14
- - `npm run test` run unit tests
15
- - `npx cdk synth` emit the synthesized CloudFormation template
16
- - `npx cdk deploy` deploy this stack to your default AWS account/region
17
- - `npx cdk diff` compare deployed stack with current state
17
+ You normally do not run this app directly:
18
18
 
19
- ## Usage
19
+ ```bash
20
+ agentcore project build # synthesizes the CloudFormation templates into agentcore/cdk/cdk.out
21
+ agentcore project deploy # synthesizes, then deploys the stack for the selected target
22
+ agentcore project status # reports the resources agentcore.json declares
23
+ ```
20
24
 
21
- You typically don't need to interact with this directory directly. The AgentCore CLI handles synthesis and deployment:
25
+ `npm run build` compiles the app, and `npx cdk synth` / `npx cdk diff` work from this directory too.
22
26
 
23
- <!-- TODO: revisit these commands once the project CLI surface is final —
24
- they may need a project prefix (e.g. --project / cwd) to disambiguate. -->
27
+ ## Extending the stack
25
28
 
26
- ```bash
27
- agentcore deploy # synthesizes and deploys via CDK
28
- agentcore status # checks deployment status
29
+ Add your own AWS resources in `lib/cdk-stack.ts` after the application and wire them to a runtime or harness through the
30
+ application's accessors. Runtimes and harnesses implement `iam.IGrantable`, so any AWS L2 grant accepts them, and they
31
+ expose `grantRead` / `grantWrite` / `grantReadWrite` for DynamoDB tables, S3 buckets and Secrets Manager secrets plus
32
+ `addEnvironmentVariable`:
33
+
34
+ ```ts
35
+ import * as dynamodb from 'aws-cdk-lib/aws-dynamodb';
36
+
37
+ const orders = new dynamodb.Table(this, 'Orders', {
38
+ partitionKey: { name: 'pk', type: dynamodb.AttributeType.STRING },
39
+ });
40
+ const checkout = this.application.runtime('checkout'); // or this.application.harness('support')
41
+ checkout.grantReadWrite(orders); // updates the runtime's execution role
42
+ checkout.addEnvironmentVariable('ORDERS_TABLE', orders.tableName);
43
+ orders.grantReadData(this.application.harness('support')); // any AWS L2 grant works too
29
44
  ```
45
+
46
+ Then run `agentcore project deploy` again. An unknown name fails at synth and lists the names that exist.
47
+
48
+ If a runtime or harness is configured with an `executionRoleArn`, CDK cannot modify that imported role: every grant
49
+ emits a synth-time warning listing the permissions that were not attached, and the role must already carry them.
50
+
51
+ `agentcore project status` reports only the resources `agentcore.json` declares; resources you add here are visible
52
+ through CloudFormation (`aws cloudformation describe-stack-resources`).
@@ -1,181 +1,30 @@
1
1
  #!/usr/bin/env node
2
- import { AgentCoreStack, type HarnessConfig } from '../lib/cdk-stack';
3
- import { ConfigIO, HarnessSpecSchema, type AwsDeploymentTarget } from '@aws/agentcore-cdk';
4
- import { App, type Environment } from 'aws-cdk-lib';
5
- import * as path from 'path';
6
- import * as fs from 'fs';
7
-
8
- function toEnvironment(target: AwsDeploymentTarget): Environment {
9
- return {
10
- account: target.account,
11
- region: target.region,
12
- };
13
- }
14
-
15
- function sanitize(name: string): string {
16
- return name.replace(/_/g, '-');
17
- }
18
-
19
- function toStackName(projectName: string, targetName: string): string {
20
- return `AgentCore-${sanitize(projectName)}-${sanitize(targetName)}`;
21
- }
22
-
23
- // The vended CDK project compiles against the published @aws/agentcore-cdk schema
24
- // type, which may lag the CLI's own AgentCoreProjectSpec (e.g. payments, harnesses,
25
- // gateway fields). This alias documents each read of those not-yet-published fields.
26
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
- type SpecWithLatestFields = any;
28
-
29
- // Extract MCP configuration from the project spec. Gateway fields are stored in
30
- // agentcore.json but may not yet be on the published spec type, so they are read
31
- // off the loosened alias.
32
- function resolveMcpSpec(spec: SpecWithLatestFields) {
33
- return spec.agentCoreGateways?.length
34
- ? {
35
- agentCoreGateways: spec.agentCoreGateways,
36
- mcpRuntimeTools: spec.mcpRuntimeTools,
37
- unassignedTargets: spec.unassignedTargets,
38
- }
39
- : undefined;
40
- }
41
-
42
- // Read non-S3 KB connector-config files and return their parsed contents keyed by
43
- // the data source's connectorConfigFile path. The L3 does not read files; it
44
- // expects these parsed connectorParameters verbatim.
45
- function resolveConnectorParametersByFile(
46
- spec: SpecWithLatestFields,
47
- projectRoot: string
48
- ): Record<string, Record<string, unknown>> {
49
- const connectorParametersByFile: Record<string, Record<string, unknown>> = {};
50
- for (const kb of spec.knowledgeBases ?? []) {
51
- for (const ds of kb.dataSources ?? []) {
52
- if (ds.type !== 'S3' && ds.connectorConfigFile) {
53
- const abs = path.resolve(projectRoot, ds.connectorConfigFile);
54
- try {
55
- connectorParametersByFile[ds.connectorConfigFile] = JSON.parse(fs.readFileSync(abs, 'utf-8'));
56
- } catch (err) {
57
- throw new Error(
58
- `Could not read connector config '${ds.connectorConfigFile}' for knowledge base '${kb.name}' at ${abs}: ${err instanceof Error ? err.message : err}`
59
- );
60
- }
61
- }
62
- }
63
- }
64
- return connectorParametersByFile;
65
- }
66
-
67
- // Synthesize a HarnessConfig for each harness entry in the spec. The full validated
68
- // spec drives the AWS::BedrockAgentCore::Harness CFN resource; the role-scoped
69
- // fields drive the IAM role + container build.
70
- function resolveHarnessConfigs(spec: SpecWithLatestFields, projectRoot: string): HarnessConfig[] {
71
- const harnessConfigs: HarnessConfig[] = [];
72
- for (const entry of spec.harnesses ?? []) {
73
- const harnessDir = path.resolve(projectRoot, entry.path);
74
- const harnessPath = path.resolve(harnessDir, 'harness.json');
75
- try {
76
- const harnessSpec = HarnessSpecSchema.parse(JSON.parse(fs.readFileSync(harnessPath, 'utf-8')));
77
- harnessConfigs.push({
78
- name: entry.name,
79
- executionRoleArn: harnessSpec.executionRoleArn,
80
- // Only an `existing` memory ref carries a name to wire IAM against; managed memory is
81
- // owned by the harness (no sibling) and disabled has none — both resolve to undefined.
82
- memoryName: harnessSpec.memory?.mode === 'existing' ? harnessSpec.memory.name : undefined,
83
- containerUri: harnessSpec.containerUri,
84
- hasDockerfile: !!harnessSpec.dockerfile,
85
- dockerfile: harnessSpec.dockerfile,
86
- codeLocation: harnessSpec.dockerfile ? harnessDir : undefined,
87
- tools: harnessSpec.tools,
88
- skills: harnessSpec.skills,
89
- apiKeyArn: harnessSpec.model?.apiKeyArn,
90
- efsAccessPoints: harnessSpec.efsAccessPoints,
91
- s3AccessPoints: harnessSpec.s3AccessPoints,
92
- apiFormat: harnessSpec.model?.apiFormat,
93
- // Full spec + dir drive the AWS::BedrockAgentCore::Harness CFN resource.
94
- spec: harnessSpec,
95
- harnessDir,
96
- });
97
- } catch (err) {
98
- throw new Error(
99
- `Could not read harness.json for "${entry.name}" at ${harnessPath}: ${err instanceof Error ? err.message : err}`
100
- );
101
- }
102
- }
103
- return harnessConfigs;
104
- }
105
-
106
- async function main() {
107
- // Config root is parent of cdk/ directory. The CLI sets process.cwd() to agentcore/cdk/.
108
- const configRoot = path.resolve(process.cwd(), '..');
109
- const configIO = new ConfigIO({ baseDir: configRoot });
110
-
111
- const spec = await configIO.readProjectSpec();
112
- const targets = await configIO.readAWSDeploymentTargets();
113
-
114
- // `project build` runs before a project has anywhere to deploy, so an empty target
115
- // list is not an error: it synthesizes a single environment-agnostic stack, which is
116
- // enough to typecheck the app and produce a template. Only a stack synthesized for a
117
- // real target is a deploy candidate; the target tag below is what marks one.
118
- const stackTargets: (AwsDeploymentTarget | undefined)[] = targets.length > 0 ? targets : [undefined];
119
-
120
- const specAny: SpecWithLatestFields = spec;
121
- const projectRoot = path.resolve(configRoot, '..');
122
-
123
- const mcpSpec = resolveMcpSpec(specAny);
124
- const connectorParametersByFile = resolveConnectorParametersByFile(specAny, projectRoot);
125
- const harnessConfigs = resolveHarnessConfigs(specAny, projectRoot);
126
-
127
- // Read deployed state for credential ARNs (populated by pre-deploy identity setup).
128
- // Under agentcore/.cli/ to match the released CLI's location.
129
- let deployedState: Record<string, unknown> | undefined;
130
- try {
131
- deployedState = JSON.parse(fs.readFileSync(path.join(configRoot, '.cli', 'deployed-state.json'), 'utf8'));
132
- } catch (err) {
133
- // A missing file is the normal first-deploy case. A malformed one is not:
134
- // surface it rather than silently synthesizing without the credential ARNs
135
- // it holds (which would drop them from the stack).
136
- if ((err as NodeJS.ErrnoException).code !== 'ENOENT') throw err;
137
- }
2
+ import { App } from 'aws-cdk-lib';
3
+ import { readAgentCoreProject, resolveTargetStacks, transformAgentCoreJson } from '@aws/agentcore-cdk';
4
+ import { AgentCoreStack } from '../lib/cdk-stack';
138
5
 
6
+ try {
7
+ // The AgentCore CLI runs this app from agentcore/cdk/; readAgentCoreProject walks up to agentcore/.
8
+ const project = readAgentCoreProject();
139
9
  const app = new App();
140
-
141
- for (const target of stackTargets) {
142
- // An environment-agnostic stack resolves its account and region from CloudFormation
143
- // pseudo-parameters at deploy time instead of pinning them at synth time.
144
- const env = target ? toEnvironment(target) : undefined;
145
- const stackName = target ? toStackName(spec.name, target.name) : `AgentCore-${sanitize(spec.name)}`;
146
-
147
- // Extract credentials from deployed state for this target
148
- const targetState = (deployedState as Record<string, unknown>)?.targets as
149
- Record<string, Record<string, unknown>> | undefined;
150
- const targetResources = target
151
- ? (targetState?.[target.name]?.resources as Record<string, unknown> | undefined)
152
- : undefined;
153
- const credentials = targetResources?.credentials as
154
- Record<string, { credentialProviderArn: string; clientSecretArn?: string }> | undefined;
155
-
156
- new AgentCoreStack(app, stackName, {
157
- spec,
158
- mcpSpec,
159
- credentials,
160
- connectorParametersByFile,
161
- harnesses: harnessConfigs.length > 0 ? harnessConfigs : undefined,
162
- env,
163
- description: target
164
- ? `AgentCore stack for ${spec.name} deployed to ${target.name} (${target.region})`
165
- : `AgentCore stack for ${spec.name} (no deployment target configured)`,
166
- // Only a stack synthesized for a real target carries the target tag, which is
167
- // how deploy selects the stack to ship.
168
- tags: {
169
- 'agentcore:project-name': spec.name,
170
- ...(target ? { 'agentcore:target-name': target.name } : {}),
171
- },
10
+ for (const stack of resolveTargetStacks({
11
+ projectName: project.projectName,
12
+ targets: project.targets,
13
+ deployedState: project.deployedState,
14
+ })) {
15
+ new AgentCoreStack(app, stack.stackName, {
16
+ env: stack.env,
17
+ tags: stack.tags,
18
+ description: stack.description,
19
+ application: transformAgentCoreJson(project.agentCoreJson, {
20
+ projectRoot: project.projectRoot,
21
+ credentials: stack.credentials,
22
+ target: stack.target,
23
+ }),
172
24
  });
173
25
  }
174
-
175
26
  app.synth();
176
- }
177
-
178
- main().catch((error: unknown) => {
27
+ } catch (error) {
179
28
  console.error('AgentCore CDK synthesis failed:', error instanceof Error ? error.message : error);
180
29
  process.exit(1);
181
- });
30
+ }