Skip to content

Commit 478ec91

Browse files
authored
feat: add runtime read-only control-plane commands (#1797)
* feat(runtime): add read-only control-plane commands Add CLI-only get and list commands for runtimes, runtime versions, and runtime endpoints with Harness-style pagination, output, injected Core clients, fixtures, and command coverage. * refactor(tui): inline runtime visibility check * docs: restore command surface wording * test(runtime): cover missing get selectors * fix(tui): show runtime in root command menu * test(runtime): consolidate command flows on golden fixtures * test(runtime): record fixtures from shared e2e account * test(runtime): clarify pagination and ID coverage * chore(runtime): clarify pagination terminology
1 parent d4c31b1 commit 478ec91

43 files changed

Lines changed: 1136 additions & 2 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,15 @@ agentcore # interactive TUI
4949
│ ├── list
5050
│ ├── update
5151
│ └── delete
52+
├── runtime # inspect deployed AgentCore Runtimes
53+
│ ├── get # fetch a Runtime by id
54+
│ ├── list # list Runtimes (server-side paginated)
55+
│ ├── version
56+
│ │ ├── get # get a specific Runtime version
57+
│ │ └── list # list a Runtime's versions
58+
│ └── endpoint
59+
│ ├── get # get a Runtime endpoint by qualifier
60+
│ └── list # list a Runtime's endpoints
5261
└── config # read/write global config values
5362
```
5463

@@ -84,6 +93,14 @@ agentcore harness invoke --id <harnessId> --session-id <session> --qualifier PRO
8493

8594
# Run a shell command inside the agent runtime
8695
agentcore harness exec --id <harnessId> --command "ls -la" --json
96+
97+
# Inspect deployed Runtimes without project configuration or deployment
98+
agentcore runtime get --id <runtimeId>
99+
agentcore runtime list --max-results 20
100+
agentcore runtime version get --id <runtimeId> --version <version>
101+
agentcore runtime version list --id <runtimeId> --max-results 20
102+
agentcore runtime endpoint get --id <runtimeId> --qualifier DEFAULT
103+
agentcore runtime endpoint list --id <runtimeId> --max-results 20
87104
```
88105

89106
---

src/components/RouterScreen.test.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ describe("menu rendering", () => {
1515
const frame = r.lastFrame()!;
1616
expect(frame).toContain("harness");
1717
expect(frame).toContain("manage agentcore harnesses");
18+
expect(frame).toContain("runtime");
19+
expect(frame).toContain("inspect AgentCore Runtimes");
1820
expect(frame).toContain("config");
1921
expect(frame).toContain("read/write global config values");
2022
r.unmount();
@@ -86,7 +88,7 @@ describe("navigation", () => {
8688
await waitForText(r.lastFrame, "❯ harness");
8789

8890
await r.press("down");
89-
await waitForText(r.lastFrame, "❯ config");
91+
await waitForText(r.lastFrame, "❯ runtime");
9092
r.unmount();
9193
});
9294

src/core/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { BedrockAgentCoreControlClient } from "@aws-sdk/client-bedrock-agentcore
22
import { BedrockAgentCoreClient } from "@aws-sdk/client-bedrock-agentcore";
33
import { IAMClient } from "@aws-sdk/client-iam";
44
import { HarnessClient } from "./harness";
5+
import { RuntimeClient } from "./runtime";
56
import type {
67
AwsClients,
78
ClientConfig,
@@ -29,6 +30,7 @@ export class CoreClient implements AwsClients {
2930

3031
// Feature-scoped sub-clients. Access as e.g. `coreClient.harness.getHarness(...)`.
3132
readonly harness: HarnessClient = new HarnessClient(this);
33+
readonly runtime: RuntimeClient = new RuntimeClient(this);
3234

3335
constructor(
3436
private readonly createControlClient: CreateControlClient,

src/core/runtime.tsx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import {
2+
GetAgentRuntimeCommand,
3+
GetAgentRuntimeEndpointCommand,
4+
ListAgentRuntimeEndpointsCommand,
5+
ListAgentRuntimesCommand,
6+
ListAgentRuntimeVersionsCommand,
7+
type GetAgentRuntimeEndpointResponse,
8+
type GetAgentRuntimeResponse,
9+
type ListAgentRuntimeEndpointsResponse,
10+
type ListAgentRuntimesResponse,
11+
type ListAgentRuntimeVersionsResponse,
12+
} from "@aws-sdk/client-bedrock-agentcore-control";
13+
import type { CoreRuntimeClient } from "../handlers/runtime/types";
14+
import type { AwsClients, CoreOptions } from "./types";
15+
import { toClientConfig } from "./utils";
16+
17+
export class RuntimeClient implements CoreRuntimeClient {
18+
constructor(private readonly clients: AwsClients) {}
19+
20+
async getRuntime(id: string, options: CoreOptions): Promise<GetAgentRuntimeResponse> {
21+
return this.clients
22+
.control(toClientConfig(options))
23+
.send(new GetAgentRuntimeCommand({ agentRuntimeId: id }));
24+
}
25+
26+
async getRuntimeVersion(
27+
id: string,
28+
version: string,
29+
options: CoreOptions,
30+
): Promise<GetAgentRuntimeResponse> {
31+
return this.clients.control(toClientConfig(options)).send(
32+
new GetAgentRuntimeCommand({
33+
agentRuntimeId: id,
34+
agentRuntimeVersion: version,
35+
}),
36+
);
37+
}
38+
39+
async getRuntimeEndpoint(
40+
id: string,
41+
qualifier: string,
42+
options: CoreOptions,
43+
): Promise<GetAgentRuntimeEndpointResponse> {
44+
return this.clients.control(toClientConfig(options)).send(
45+
new GetAgentRuntimeEndpointCommand({
46+
agentRuntimeId: id,
47+
endpointName: qualifier,
48+
}),
49+
);
50+
}
51+
52+
async listRuntimes(
53+
nextToken: string | undefined,
54+
maxResults: number | undefined,
55+
options: CoreOptions,
56+
): Promise<ListAgentRuntimesResponse> {
57+
return this.clients
58+
.control(toClientConfig(options))
59+
.send(new ListAgentRuntimesCommand({ nextToken, maxResults }));
60+
}
61+
62+
async listRuntimeVersions(
63+
id: string,
64+
nextToken: string | undefined,
65+
maxResults: number | undefined,
66+
options: CoreOptions,
67+
): Promise<ListAgentRuntimeVersionsResponse> {
68+
return this.clients.control(toClientConfig(options)).send(
69+
new ListAgentRuntimeVersionsCommand({
70+
agentRuntimeId: id,
71+
nextToken,
72+
maxResults,
73+
}),
74+
);
75+
}
76+
77+
async listRuntimeEndpoints(
78+
id: string,
79+
nextToken: string | undefined,
80+
maxResults: number | undefined,
81+
options: CoreOptions,
82+
): Promise<ListAgentRuntimeEndpointsResponse> {
83+
return this.clients.control(toClientConfig(options)).send(
84+
new ListAgentRuntimeEndpointsCommand({
85+
agentRuntimeId: id,
86+
nextToken,
87+
maxResults,
88+
}),
89+
);
90+
}
91+
}

src/handlers/index.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Router } from "../router";
22
import { createHarnessHandler } from "./harness/index.tsx";
3+
import { createRuntimeHandler } from "./runtime/index.tsx";
34
import { DebugKey, EndpointKey, JsonKey, RegionKey } from "./keys.tsx";
45
import { createConfigHandler } from "./config/";
56
import { createProjectHandler } from "./project/index.ts";
@@ -33,6 +34,7 @@ export function createRootHandler(core: Core, config: RootHandlerConfig): Router
3334

3435
// Install sub handlers
3536
root.handler(createHarnessHandler(core, io));
37+
root.handler(createRuntimeHandler(core, io));
3638
root.handler(createConfigHandler(io));
3739
root.handler(createProjectHandler());
3840

src/handlers/root.test.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ describe("createRootHandler", () => {
99
logger: createSilentLogger(),
1010
});
1111
expect(root.name()).toBe("agentcore");
12-
expect(root.children().map((c) => c.name())).toEqual(["harness", "config", "project"]);
12+
expect(root.children().map((c) => c.name())).toEqual([
13+
"harness",
14+
"runtime",
15+
"config",
16+
"project",
17+
]);
1318
});
1419
});
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"agentRuntimeArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:runtime/agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx",
3+
"agentRuntimeName": "agentcore_cli_runtime_read_only_fixture",
4+
"agentRuntimeId": "agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx",
5+
"agentRuntimeVersion": "2",
6+
"createdAt": {
7+
"$date": "2026-07-21T15:24:52.318Z"
8+
},
9+
"lastUpdatedAt": {
10+
"$date": "2026-07-21T15:25:21.499Z"
11+
},
12+
"roleArn": "arn:aws:iam::685197708687:role/tf_acc_test_1997929140646926281",
13+
"networkConfiguration": {
14+
"networkMode": "PUBLIC"
15+
},
16+
"status": "READY",
17+
"lifecycleConfiguration": {
18+
"idleRuntimeSessionTimeout": 900,
19+
"maxLifetime": 28800
20+
},
21+
"description": "Stable shared resource for AgentCore CLI Runtime read-only fixture recording",
22+
"workloadIdentityDetails": {
23+
"workloadIdentityArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:workload-identity-directory/default/workload-identity/agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx"
24+
},
25+
"agentRuntimeArtifact": {
26+
"containerConfiguration": {
27+
"containerUri": "public.ecr.aws/y5s8y8h8/harness-us-west-2:latest"
28+
}
29+
},
30+
"metadataConfiguration": {
31+
"requireMMDSV2": true
32+
}
33+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"agentRuntimeArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:runtime/agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx",
3+
"agentRuntimeName": "agentcore_cli_runtime_read_only_fixture",
4+
"agentRuntimeId": "agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx",
5+
"agentRuntimeVersion": "1",
6+
"createdAt": {
7+
"$date": "2026-07-21T15:24:53.572Z"
8+
},
9+
"lastUpdatedAt": {
10+
"$date": "2026-07-21T15:24:53.572Z"
11+
},
12+
"roleArn": "arn:aws:iam::685197708687:role/tf_acc_test_1997929140646926281",
13+
"networkConfiguration": {
14+
"networkMode": "PUBLIC"
15+
},
16+
"status": "READY",
17+
"lifecycleConfiguration": {
18+
"idleRuntimeSessionTimeout": 900,
19+
"maxLifetime": 28800
20+
},
21+
"description": "Stable shared resource for AgentCore CLI Runtime read-only fixture recording",
22+
"workloadIdentityDetails": {
23+
"workloadIdentityArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:workload-identity-directory/default/workload-identity/agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx"
24+
},
25+
"agentRuntimeArtifact": {
26+
"containerConfiguration": {
27+
"containerUri": "public.ecr.aws/y5s8y8h8/harness-us-west-2:latest"
28+
}
29+
},
30+
"metadataConfiguration": {
31+
"requireMMDSV2": true
32+
}
33+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"$error": {
3+
"name": "ResourceNotFoundException",
4+
"message": "Agent with agentId: missing_runtime-0000000000, accountId: 685197708687, and version: null not found!"
5+
}
6+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"agentRuntimeEndpointArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:runtime/agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx/runtime-endpoint/DEFAULT",
3+
"agentRuntimeArn": "arn:aws:bedrock-agentcore:us-west-2:685197708687:runtime/agentcore_cli_runtime_read_only_fixture-wZ7V4Q6vhx",
4+
"status": "READY",
5+
"createdAt": {
6+
"$date": "2026-07-21T15:24:52.560Z"
7+
},
8+
"lastUpdatedAt": {
9+
"$date": "2026-07-21T15:25:21.499Z"
10+
},
11+
"name": "DEFAULT",
12+
"id": "DEFAULT",
13+
"liveVersion": "2"
14+
}

0 commit comments

Comments
 (0)