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
32 changes: 22 additions & 10 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,28 @@ src/

Note: CDK L3 constructs are in a separate package `@aws/agentcore-cdk`.

## Global Options

These options are available on all commands:

- `-h, --help` - Show help for any command
- `--version` - Print CLI version (root command only)

## CLI Commands

- `create` - Create new AgentCore project
- `add` - Add resources (agent, memory, identity, evaluator, online-eval, target)
- `remove` - Remove resources (agent, memory, identity, evaluator, online-eval, target, all)
- `add` - Add resources (agent, memory, identity, evaluator, online-eval, gateway, gateway-target, policy-engine,
policy)
- `remove` - Remove resources (agent, memory, identity, evaluator, online-eval, gateway, gateway-target, policy-engine,
policy, all)
- `deploy` - Deploy infrastructure to AWS
- `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)
- `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
- `import` - Import resources from a Bedrock AgentCore Starter Toolkit project
- `pause online-eval` - Pause (disable) a deployed online eval config
- `resume online-eval` - Resume (enable) a paused online eval config
- `logs` - Stream or search agent runtime logs
Expand All @@ -45,8 +56,7 @@ Note: CDK L3 constructs are in a separate package `@aws/agentcore-cdk`.

### Agent Types

- **Template agents**: Created from framework templates (Strands, LangChain_LangGraph, CrewAI, GoogleADK, OpenAIAgents,
AutoGen)
- **Template agents**: Created from framework templates (Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents)
- **BYO agents**: Bring your own code with `agentcore add agent --type byo`
- **Imported agents**: Import from Bedrock Agents with `agentcore add agent --type import`

Expand All @@ -58,10 +68,10 @@ Note: CDK L3 constructs are in a separate package `@aws/agentcore-cdk`.

## Primitives Architecture

All resource types (agent, memory, identity, evaluator, online-eval, gateway, mcp-tool) are modeled as **primitives** --
self-contained classes in `src/cli/primitives/` that own the full add/remove lifecycle for their resource type.
Resources support config-driven tagging via `agentcore.json` and `mcp.json`, with tags flowing through to deployed
CloudFormation resources.
All resource types (agent, memory, identity, evaluator, online-eval, gateway, gateway-target, policy-engine, policy) are
modeled as **primitives** -- self-contained classes in `src/cli/primitives/` that own the full add/remove lifecycle for
their resource type. Resources support config-driven tagging via `agentcore.json` and `mcp.json`, with tags flowing
through to deployed CloudFormation resources.

Each primitive extends `BasePrimitive` and implements: `add()`, `remove()`, `previewRemove()`, `getRemovable()`,
`registerCommands()`, and `addScreen()`.
Expand All @@ -73,8 +83,10 @@ Current primitives:
- `CredentialPrimitive` — credential/identity creation, .env management, removal
- `EvaluatorPrimitive` — custom evaluator creation/removal with cross-reference validation
- `OnlineEvalConfigPrimitive` — online eval config creation/removal
- `GatewayPrimitive` — MCP gateway creation/removal
- `GatewayTargetPrimitive` — MCP tool creation/removal with code generation
- `GatewayPrimitive` — gateway creation/removal
- `GatewayTargetPrimitive` — gateway target creation/removal with code generation
- `PolicyEnginePrimitive` — Cedar policy engine creation/removal
- `PolicyPrimitive` — Cedar policy creation/removal within policy engines

Singletons are created in `registry.ts` and wired into CLI commands via `cli.ts`. See `src/cli/AGENTS.md` for details on
adding new primitives.
Expand Down
4 changes: 2 additions & 2 deletions src/cli/commands/create/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,14 @@ export const registerCreate = (program: Command) => {
program
.command('create')
.description(COMMAND_DESCRIPTIONS.create)
.option('--name <name>', 'Project name (start with letter, alphanumeric only, max 36 chars) [non-interactive]')
.option('--name <name>', 'Project name (start with letter, alphanumeric only, max 23 chars) [non-interactive]')
.option('--no-agent', 'Skip agent creation [non-interactive]')
.option('--defaults', 'Use defaults (Python, Strands, Bedrock, no memory) [non-interactive]')
.option('--build <type>', 'Build type: CodeZip or Container (default: CodeZip) [non-interactive]')
.option('--language <language>', 'Target language (default: Python) [non-interactive]')
.option(
'--framework <framework>',
'Agent framework (Strands, LangChain_LangGraph, CrewAI, GoogleADK, OpenAIAgents) [non-interactive]'
'Agent framework (Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents) [non-interactive]'
)
.option('--model-provider <provider>', 'Model provider (Bedrock, Anthropic, OpenAI, Gemini) [non-interactive]')
.option('--api-key <key>', 'API key for non-Bedrock providers [non-interactive]')
Expand Down
6 changes: 3 additions & 3 deletions src/cli/commands/dev/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -142,11 +142,11 @@ export const registerDev = (program: Command) => {
.option('-i, --invoke <prompt>', 'Invoke running dev server (use --agent if multiple) [non-interactive]')
.option('-s, --stream', 'Stream response when using --invoke [non-interactive]')
.option('-l, --logs', 'Run dev server with logs to stdout [non-interactive]')
.option('--tool <name>', 'MCP tool name (used with --invoke call-tool)')
.option('--input <json>', 'MCP tool arguments as JSON (used with --invoke call-tool)')
.option('--tool <name>', 'MCP tool name (used with --invoke call-tool) [non-interactive]')
.option('--input <json>', 'MCP tool arguments as JSON (used with --invoke call-tool) [non-interactive]')
.option(
'-H, --header <header>',
'Custom header to forward to the agent (format: "Name: Value", repeatable)',
'Custom header to forward to the agent (format: "Name: Value", repeatable) [non-interactive]',
(val: string, prev: string[]) => [...prev, val],
[] as string[]
)
Expand Down
8 changes: 4 additions & 4 deletions src/cli/commands/fetch/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ export const registerFetch = (program: Command) => {
fetchCmd
.command('access')
.description('Fetch access info (URL, token, auth guidance) for a deployed gateway or agent.')
.option('--name <resource>', 'Gateway or agent name')
.option('--type <type>', 'Resource type: gateway (default) or agent', 'gateway')
.option('--target <target>', 'Deployment target')
.option('--json', 'Output as JSON')
.option('--name <resource>', 'Gateway or agent name [non-interactive]')
.option('--type <type>', 'Resource type: gateway (default) or agent [non-interactive]', 'gateway')
.option('--target <target>', 'Deployment target [non-interactive]')
.option('--json', 'Output as JSON [non-interactive]')
.action(async (cliOptions: Record<string, unknown>) => {
const options = cliOptions as unknown as FetchAccessOptions;
requireProject();
Expand Down
2 changes: 1 addition & 1 deletion src/cli/commands/invoke/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export const registerInvoke = (program: Command) => {
.option('--input <json>', 'MCP tool arguments as JSON (use with --tool) [non-interactive]')
.option(
'-H, --header <header>',
'Custom header to forward to the agent (format: "Name: Value", repeatable)',
'Custom header to forward to the agent (format: "Name: Value", repeatable) [non-interactive]',
(val: string, prev: string[]) => [...prev, val],
[] as string[]
)
Expand Down
5 changes: 4 additions & 1 deletion src/cli/commands/status/command.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,10 @@
.description(COMMAND_DESCRIPTIONS.status)
.option('--agent-runtime-id <id>', 'Look up a specific agent runtime by ID')
.option('--target <name>', 'Select deployment target')
.option('--type <type>', 'Filter by resource type (agent, memory, credential, gateway, policy-engine, policy)')
.option(
'--type <type>',
'Filter by resource type (agent, memory, credential, gateway, evaluator, online-eval, policy-engine, policy)'
)
.option('--state <state>', 'Filter by deployment state (deployed, local-only, pending-removal)')
.option('--agent <name>', 'Filter to a specific agent')
.option('--json', 'Output as JSON')
Expand Down Expand Up @@ -229,7 +232,7 @@
});
};

function ResourceEntry({ entry, showRuntime }: { entry: ResourceStatusEntry; showRuntime?: boolean }) {

Check warning on line 235 in src/cli/commands/status/command.tsx

View workflow job for this annotation

GitHub Actions / lint

Fast refresh only works when a file only exports components. Move your component(s) to a separate file. If all exports are HOCs, add them to the `extraHOCs` option
return (
<Text>
{' '}
Expand Down
11 changes: 6 additions & 5 deletions src/cli/primitives/AgentPrimitive.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export interface AddAgentOptions extends VpcOptions {
export class AgentPrimitive extends BasePrimitive<AddAgentOptions, RemovableResource> {
readonly kind = 'agent';
readonly label = 'Agent';
protected override readonly article = 'an';
readonly primitiveSchema = AgentEnvSpecSchema;

/** Local instance to avoid circular dependency with registry. */
Expand Down Expand Up @@ -195,14 +196,14 @@ export class AgentPrimitive extends BasePrimitive<AddAgentOptions, RemovableReso
addCmd
.command('agent')
.description('Add an agent to the project')
.option('--name <name>', 'Agent name (start with letter, alphanumeric only, max 64 chars) [non-interactive]')
.option(
'--name <name>',
'Agent name (start with letter, alphanumeric and underscores only, max 48 chars) [non-interactive]'
)
.option('--type <type>', 'Agent type: create, byo, or import [non-interactive]', 'create')
.option('--build <type>', 'Build type: CodeZip or Container (default: CodeZip) [non-interactive]')
.option('--language <lang>', 'Language: Python (create), or Python/TypeScript/Other (BYO) [non-interactive]')
.option(
'--framework <fw>',
'Framework: Strands, LangChain_LangGraph, CrewAI, GoogleADK, OpenAIAgents [non-interactive]'
)
.option('--framework <fw>', 'Framework: Strands, LangChain_LangGraph, GoogleADK, OpenAIAgents [non-interactive]')
.option('--model-provider <provider>', 'Model provider: Bedrock, Anthropic, OpenAI, Gemini [non-interactive]')
.option('--api-key <key>', 'API key for non-Bedrock providers [non-interactive]')
.option('--memory <mem>', 'Memory: none, shortTerm, longAndShortTerm (create path only) [non-interactive]')
Expand Down
17 changes: 10 additions & 7 deletions src/cli/primitives/EvaluatorPrimitive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,19 +124,22 @@ export class EvaluatorPrimitive extends BasePrimitive<AddEvaluatorOptions, Remov
addCmd
.command(this.kind)
.description('Add a custom evaluator to the project')
.option('--name <name>', 'Evaluator name')
.option('--level <level>', 'Evaluation level: SESSION, TRACE, TOOL_CALL')
.option('--model <model>', 'Bedrock model ID for LLM-as-a-Judge')
.option('--name <name>', 'Evaluator name [non-interactive]')
.option('--level <level>', 'Evaluation level: SESSION, TRACE, TOOL_CALL [non-interactive]')
.option('--model <model>', 'Bedrock model ID for LLM-as-a-Judge [non-interactive]')
.option(
'--instructions <text>',
'Evaluation prompt instructions (must include level-appropriate placeholders, e.g. {context})'
'Evaluation prompt instructions (must include level-appropriate placeholders, e.g. {context}) [non-interactive]'
)
.option(
'--rating-scale <preset>',
`Rating scale preset: ${presetIds.join(', ')} (default: 1-5-quality) [non-interactive]`
)
.option('--rating-scale <preset>', `Rating scale preset: ${presetIds.join(', ')} (default: 1-5-quality)`)
.option(
'--config <path>',
'Path to evaluator config JSON file (overrides --model, --instructions, --rating-scale)'
'Path to evaluator config JSON file (overrides --model, --instructions, --rating-scale) [non-interactive]'
)
.option('--json', 'Output as JSON')
.option('--json', 'Output as JSON [non-interactive]')
.action(
async (cliOptions: {
name?: string;
Expand Down
44 changes: 24 additions & 20 deletions src/cli/primitives/GatewayPrimitive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,23 +158,27 @@ export class GatewayPrimitive extends BasePrimitive<AddGatewayOptions, Removable
registerCommands(addCmd: Command, removeCmd: Command): void {
addCmd
.command('gateway')
.description('Add a gateway to the project')
.option('--name <name>', 'Gateway name')
.option('--description <desc>', 'Gateway description')
.option('--authorizer-type <type>', 'Authorizer type: NONE or CUSTOM_JWT')
.option('--discovery-url <url>', 'OIDC discovery URL (for CUSTOM_JWT)')
.option('--allowed-audience <audience>', 'Comma-separated allowed audiences (for CUSTOM_JWT)')
.option('--allowed-clients <clients>', 'Comma-separated allowed client IDs (for CUSTOM_JWT)')
.option('--allowed-scopes <scopes>', 'Comma-separated allowed scopes (for CUSTOM_JWT)')
.option('--custom-claims <json>', 'Custom claim validations as JSON array (for CUSTOM_JWT)')
.option('--client-id <id>', 'OAuth client ID for gateway bearer token')
.option('--client-secret <secret>', 'OAuth client secret')
.option('--agents <agents>', 'Comma-separated agent names')
.option('--no-semantic-search', 'Disable semantic search for tool discovery')
.option('--exception-level <level>', 'Exception verbosity level', 'NONE')
.option('--policy-engine <name>', 'Policy engine name for Cedar-based authorization')
.option('--policy-engine-mode <mode>', 'Policy engine mode: LOG_ONLY or ENFORCE')
.option('--json', 'Output as JSON')
.description('Add an API gateway that routes requests to agent targets')
.option('--name <name>', 'Gateway name [non-interactive]')
.option('--description <desc>', 'Gateway description [non-interactive]')
.option('--agents <agents>', 'Comma-separated agent names to expose through this gateway [non-interactive]')
.option('--authorizer-type <type>', 'Authorizer type: NONE or CUSTOM_JWT [non-interactive]')
.option('--discovery-url <url>', 'OIDC discovery URL (for CUSTOM_JWT) [non-interactive]')
.option('--allowed-audience <audience>', 'Comma-separated allowed audiences (for CUSTOM_JWT) [non-interactive]')
.option('--allowed-clients <clients>', 'Comma-separated allowed client IDs (for CUSTOM_JWT) [non-interactive]')
.option('--allowed-scopes <scopes>', 'Comma-separated allowed scopes (for CUSTOM_JWT) [non-interactive]')
.option('--custom-claims <json>', 'Custom claim validations as JSON array (for CUSTOM_JWT) [non-interactive]')
.option('--client-id <id>', 'OAuth client ID for fetching gateway bearer tokens [non-interactive]')
.option('--client-secret <secret>', 'OAuth client secret for fetching gateway bearer tokens [non-interactive]')
.option('--no-semantic-search', 'Disable semantic search for gateway target tool discovery [non-interactive]')
.option(
'--exception-level <level>',
'Exception detail level in error responses: NONE, ALL [non-interactive]',
'NONE'
)
.option('--policy-engine <name>', 'Policy engine name for Cedar-based authorization [non-interactive]')
.option('--policy-engine-mode <mode>', 'Policy engine mode: LOG_ONLY or ENFORCE [non-interactive]')
.option('--json', 'Output as JSON [non-interactive]')
.action(async (rawOptions: Record<string, string | boolean | undefined>) => {
const cliOptions = rawOptions as unknown as CLIAddGatewayOptions;
try {
Expand Down Expand Up @@ -238,9 +242,9 @@ export class GatewayPrimitive extends BasePrimitive<AddGatewayOptions, Removable
removeCmd
.command('gateway')
.description('Remove a gateway from the project')
.option('--name <name>', 'Name of resource to remove')
.option('--force', 'Skip confirmation prompt')
.option('--json', 'Output as JSON')
.option('--name <name>', 'Name of resource to remove [non-interactive]')
.option('--force', 'Skip confirmation prompt [non-interactive]')
.option('--json', 'Output as JSON [non-interactive]')
.action(async (cliOptions: { name?: string; force?: boolean; json?: boolean }) => {
try {
if (!findConfigRoot()) {
Expand Down
Loading
Loading