@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.
- package/README.md +251 -11
- package/dist/assets/cdk/README.md +42 -19
- package/dist/assets/cdk/bin/cdk.ts +22 -173
- package/dist/assets/cdk/lib/cdk-stack.ts +18 -80
- package/dist/assets/cdk/package.json +3 -10
- package/dist/assets/cdk/tsconfig.json +1 -1
- package/dist/assets/evaluators/python-lambda/README.md +5 -1
- package/dist/assets/templates/a2a-python-strands/pyproject.toml +1 -1
- package/dist/assets/templates/agent-python-langchain/README.md +4 -3
- package/dist/assets/templates/agent-python-langchain/main.py +7 -11
- package/dist/assets/templates/agent-python-strands/README.md +16 -2
- package/dist/assets/templates/agent-python-strands/main.py +40 -81
- package/dist/assets/templates/agent-python-strands/memory/session.py +1 -5
- package/dist/assets/templates/agent-python-strands/model/load.py +4 -4
- package/dist/assets/templates/agent-python-strands/parse.py +41 -0
- package/dist/assets/templates/agent-typescript-strands/README.md +23 -2
- package/dist/assets/templates/agent-typescript-strands/main.ts +4 -13
- package/dist/assets/templates/agent-typescript-strands/memory/memory.ts +1 -12
- package/dist/assets/templates/agent-typescript-strands/package.json.template +0 -1
- package/dist/assets/templates/agui-python-strands/pyproject.toml +1 -1
- package/dist/assets/templates/export-harness-python/model/load.py +3 -3
- package/dist/assets/templates/harness/harness.yaml +157 -0
- package/dist/main.js +524 -132
- package/package.json +6 -4
- package/dist/assets/cdk/.prettierrc +0 -8
- package/dist/assets/cdk/jest.config.js +0 -9
- package/dist/assets/cdk/npmignore.template +0 -6
- package/dist/assets/cdk/test/cdk.test.ts +0 -120
- package/dist/assets/evaluators/autoevals-lambda/README.md +0 -23
- package/dist/assets/evaluators/autoevals-lambda/execution-role-policy.json +0 -15
- package/dist/assets/evaluators/autoevals-lambda/lambda_function.py +0 -37
- package/dist/assets/evaluators/autoevals-lambda/pyproject.toml +0 -23
- package/dist/assets/evaluators/deepeval-lambda/README.md +0 -23
- package/dist/assets/evaluators/deepeval-lambda/execution-role-policy.json +0 -15
- package/dist/assets/evaluators/deepeval-lambda/lambda_function.py +0 -29
- package/dist/assets/evaluators/deepeval-lambda/pyproject.toml +0 -22
- 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
|
-
│
|
|
66
|
-
│
|
|
67
|
-
│
|
|
68
|
-
│
|
|
69
|
-
│
|
|
70
|
-
│
|
|
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
|
-
│
|
|
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)
|
|
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`
|
|
971
|
-
|
|
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
|
|
1
|
+
# AgentCore CDK app
|
|
2
2
|
|
|
3
|
-
This CDK
|
|
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
|
-
|
|
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
|
-
|
|
8
|
-
|
|
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
|
-
##
|
|
15
|
+
## The CLI runs it for you
|
|
12
16
|
|
|
13
|
-
|
|
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
|
-
|
|
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
|
-
|
|
25
|
+
`npm run build` compiles the app, and `npx cdk synth` / `npx cdk diff` work from this directory too.
|
|
22
26
|
|
|
23
|
-
|
|
24
|
-
they may need a project prefix (e.g. --project / cwd) to disambiguate. -->
|
|
27
|
+
## Extending the stack
|
|
25
28
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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 {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
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
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
+
}
|