Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all
 blocks
(function() {
function addCopyButtons() {
document.querySelectorAll('pre code').forEach(function(codeBlock) {
if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;
codeBlock.parentElement.setAttribute('data-copy-added', 'true');
var btn = document.createElement('button');
btn.textContent = 'Copy';
btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';
btn.onmouseover = function() { this.style.opacity = '1'; };
btn.onmouseout = function() { this.style.opacity = '0.7'; };
btn.onclick = function() {
navigator.clipboard.writeText(codeBlock.textContent).then(function() {
btn.textContent = 'Copied!';
setTimeout(function() { btn.textContent = 'Copy'; }, 1500);
});
};
codeBlock.parentElement.style.position = 'relative';
codeBlock.parentElement.appendChild(btn);
});
}
addCopyButtons();
// Re-run on dynamic content
var observer = new MutationObserver(addCopyButtons);
observer.observe(document.body, { childList: true, subtree: true });
})();
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); feat(capacity-provider): complete CLI DevEx for journeys 2-4 (attach, volumes, TUI wizard, J4 delete-session) by xxuam · Pull Request #2133 · aws/agentcore-cli · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AGENTS.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -39,6 +39,7 @@ These options are available on all commands:
- `status` - Check deployment status
- `dev` - Local development server (CodeZip: uvicorn with hot-reload; Container: Docker build + run with volume mount)
- `invoke` - Invoke agents (local or deployed)
- `capacity-provider delete-session` - Delete (deprovision) a live capacity provider session (data-plane)
- `run eval` - Run on-demand evaluation against agent sessions
- `evals history` - View past eval run results
- `fetch access` - Fetch access info for a deployed gateway or agent
Expand Down
37 changes: 35 additions & 2 deletions docs/commands.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -318,6 +318,9 @@ agentcore add agent \
| `--client-secret <secret>` | OAuth client secret |
| `--request-header-allowlist <headers>` | Comma-separated list of inbound header names to forward to the agent. `X-*` names (e.g. `X-Api-Key`, `X-Custom-Signature`) pass through unchanged; bare names without an `X-` prefix are auto-prefixed with the legacy `X-Amzn-Bedrock-AgentCore-Runtime-Custom-` prefix for backward compatibility. |
| `--session-storage-mount-path <path>` | Absolute mount path for session filesystem storage (e.g. `/mnt/session-storage`) |
| `--capacity-provider <name-or-arn>` | Attach the runtime to a capacity provider (customer-managed EC2 compute). Accepts an in-project capacity-provider name or an external CP ARN. Mutually exclusive with `--network-mode VPC`. |
| `--cp-volume-name <name>` | Capacity provider volume name to mount (repeatable, paired by position with `--cp-volume-mount-path`). The name must match a volume defined on the attached capacity provider. |
| `--cp-volume-mount-path <path>` | Capacity provider volume mount path under `/mnt` (e.g. `/mnt/models`, repeatable, paired with `--cp-volume-name`) |
| `--with-config-bundle` | Wire a config bundle into the generated agent template |
| `--idle-timeout <seconds>` | Idle session timeout in seconds |
| `--max-lifetime <seconds>` | Max instance lifetime in seconds |
Expand DownExpand Up@@ -814,7 +817,7 @@ agentcore add capacity-provider \
--security-groups sg-0123456789abcdef0 \
--os LINUX_ARM64 \
--instance-types c7g.large,c7g.xlarge \
--volume data:20 --volume-encrypted \
--volume-name data --volume-size 20 --volume-encrypted \
--idle-instance-timeout 3600 \
--max-lifetime 28800
```
Expand All@@ -828,7 +831,8 @@ agentcore add capacity-provider \
| `--security-groups <groups>` | Comma-separated security group IDs, 1–16 (required) |
| `--os <os>` | `LINUX_X86_64` (default) or `LINUX_ARM64` |
| `--instance-types <types>` | Comma-separated allowed EC2 instance types, 1–30 (required) |
| `--volume <name:sizeGiB>` | Named EBS volume as `name:sizeGiB` (repeatable, max 5) |
| `--volume-name <name>` | Named EBS volume name (repeatable, max 5; paired with `--volume-size`) |
| `--volume-size <sizeGiB>` | EBS volume size in GiB (repeatable; paired with `--volume-name`) |
| `--volume-encrypted` | Encrypt EBS volumes |
| `--volume-kms-key <arn>` | KMS key ARN for EBS volume encryption |
| `--instance-profile-arn <arn>` | IAM instance profile ARN for launched instances |
Expand DownExpand Up@@ -905,6 +909,35 @@ agentcore dev call-tool --tool myTool --input '{"arg": "value"}'
| `-b, --no-browser` | Use terminal TUI instead of web-based chat UI |
| `--no-traces` | Disable local OTEL trace collection |

### capacity-provider delete-session

Delete (deprovision) a single live capacity provider session. This is a data-plane operation: it terminates the
session's EC2 instance and **permanently deletes any persistent EBS volumes** attached to the session (data loss). The
operation is asynchronous — it returns immediately with status `Deprovisioning`. You get the session id from `invoke`
(it echoes the session it used); there is no list-sessions API.

```bash
# By in-project capacity provider name (resolved to its id from deployed state)
agentcore capacity-provider delete-session --capacity-provider my-pool --session-id <sessionId>

# By capacity provider id, without a project (the data-plane API is keyed on the id)
agentcore capacity-provider delete-session \
--capacity-provider my-pool-a1b2c3d4e5 --session-id <sessionId> --region us-west-2 --yes

# By ARN (the id is extracted from it), without a project (region auto-detected from the ARN)
agentcore capacity-provider delete-session \
--capacity-provider arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/my-pool-a1b2c3d4e5 \
--session-id <sessionId> --yes
```

| Option | Description |
| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--capacity-provider <name-id-or-arn>` | Capacity provider: an in-project name (resolved to its id via deployed state), a capacity provider id, or an ARN (id extracted from it). The API is keyed on the id. (**required**) |
| `--session-id <id>` | Session id to delete (**required**) |
| `--region <region>` | AWS region (auto-detected from the ARN / project otherwise; required with a bare id outside a project unless the environment sets one) |
| `--yes` | Skip the destructive confirmation prompt (required for non-interactive use) |
| `--json` | JSON output |

### invoke

Invoke a deployed agent endpoint.
Expand Down
194 changes: 194 additions & 0 deletions integ-tests/add-agent-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
import { createTestProject, readProjectConfig, runCLI } from '../src/test-utils/index.js';
import type { TestProject } from '../src/test-utils/index.js';
import { afterAll, beforeAll, describe, expect, it } from 'vitest';

const OPERATOR_ROLE_ARN = 'arn:aws:iam::123456789012:role/MyOperatorRole';

describe('integration: attach capacity provider to an agent (J2/J3) + delete-session (J4)', () => {
let project: TestProject;
const cpName = `IntegAttachCp${Date.now().toString().slice(-6)}`;

beforeAll(async () => {
project = await createTestProject({ noAgent: true });
// A capacity provider with a named volume for the runtime to mount (J3).
const cp = await runCLI(
[
'add',
'capacity-provider',
'--name',
cpName,
'--operator-role-arn',
OPERATOR_ROLE_ARN,
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--os',
'LINUX_X86_64',
'--instance-types',
'c6a.large',
'--volume-name',
'model-weights',
'--volume-size',
'100',
'--json',
],
project.projectPath
);
expect(cp.exitCode, `stdout: ${cp.stdout}, stderr: ${cp.stderr}`).toBe(0);
});

afterAll(async () => {
await project.cleanup();
});

it('attaches a BYO agent to a sibling capacity provider by name and mounts a CP volume', async () => {
const agentName = 'CpAttachAgent';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
cpName,
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
expect(JSON.parse(result.stdout).success).toBe(true);

const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent, `Agent "${agentName}" should be in config`).toBeTruthy();
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderName: cpName });
expect(agent!.filesystemConfigurations).toContainEqual({
capacityProviderVolume: { volumeName: 'model-weights', mountPath: '/mnt/models' },
});
});

it('attaches a BYO agent to an external capacity provider by ARN', async () => {
const agentName = 'CpArnAgent';
const arn = 'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/ext_pool-a1b2c3d4e5';
const result = await runCLI(
[
'add',
'agent',
'--name',
agentName,
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
`apps/${agentName}`,
'--capacity-provider',
arn,
'--json',
],
project.projectPath
);

expect(result.exitCode, `stdout: ${result.stdout}, stderr: ${result.stderr}`).toBe(0);
const config = await readProjectConfig(project.projectPath);
const agent = config.runtimes.find(a => a.name === agentName);
expect(agent!.capacityProviderConfiguration).toEqual({ capacityProviderArn: arn });
});

it('rejects a CP volume mount without a capacity provider attachment', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVolNoAttach',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVolNoAttach',
'--cp-volume-name',
'model-weights',
'--cp-volume-mount-path',
'/mnt/models',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('rejects attaching a capacity provider together with VPC networking', async () => {
const result = await runCLI(
[
'add',
'agent',
'--name',
'CpVpcAgent',
'--type',
'byo',
'--language',
'Python',
'--framework',
'Strands',
'--model-provider',
'Bedrock',
'--code-location',
'apps/CpVpcAgent',
'--capacity-provider',
cpName,
'--network-mode',
'VPC',
'--subnets',
'subnet-0123456789abcdef0',
'--security-groups',
'sg-0123456789abcdef0',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});

it('delete-session rejects an invalid session id', async () => {
const result = await runCLI(
[
'capacity-provider',
'delete-session',
'--capacity-provider',
'arn:aws:bedrock-agentcore:us-west-2:123456789012:capacity-provider/x_pool-a1b2c3d4e5',
'--session-id',
'bad session id',
'--yes',
'--json',
],
project.projectPath
);
expect(result.exitCode).not.toBe(0);
});
});
6 changes: 4 additions & 2 deletions integ-tests/add-remove-capacity-provider.test.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -78,8 +78,10 @@ describe('integration: add and remove capacity providers', () => {
'LINUX_ARM64',
'--instance-types',
'c7g.large,c7g.xlarge',
'--volume',
'data:20',
'--volume-name',
'data',
'--volume-size',
'20',
'--volume-encrypted',
'--idle-instance-timeout',
'3600',
Expand Down
Loading
Loading