Skip to content

refactor: align templates with old cli definition - #2094

Merged
Hweinstock merged 6 commits into
aws:refactorfrom
Hweinstock:refactor-templates
Aug 26, 2026
Merged

refactor: align templates with old cli definition#2094
Hweinstock merged 6 commits into
aws:refactorfrom
Hweinstock:refactor-templates

Conversation

@Hweinstock

@Hweinstock Hweinstock commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Problem

The new CLI has a new definition of templates that is not fully flushed out and diverges from the old CLI. We want to get e2e functionality first, before rethinking this.

Solution

  • Templates now again refer to the asset rendering, and the flag for templates refers to flag presets.
  • remove byo support to simplify runtime handler for initial version.
  • bring parity to create flags to what was discussed in (basically what was in the old cli).
  • adjust runtime flags to match the create flags.
  • make minimal backend changes to support new interface.

Future Work

Want to refactor the templates to split up template parameters from template identifiers (i.e. what determines the base vs rendered in with handlebars. )

Testing

  • added unit tests that exercise the command e2e.

@github-actions github-actions Bot added agentcore-harness-reviewing AgentCore Harness review in progress and removed agentcore-harness-reviewing AgentCore Harness review in progress labels Aug 24, 2026
@codecov-commenter

codecov-commenter commented Aug 24, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.42%. Comparing base (1593e2d) to head (e295d4e).

Additional details and impacted files
@@            Coverage Diff            @@
##           refactor    #2094   +/-   ##
=========================================
  Coverage     97.41%   97.42%           
=========================================
  Files           428      428           
  Lines         26096    26124   +28     
=========================================
+ Hits          25422    25450   +28     
  Misses          674      674           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Hweinstock
Hweinstock force-pushed the refactor-templates branch 4 times, most recently from 4c16ba0 to 4a80a21 Compare August 24, 2026 22:32
},
};

function buildRuntimeTemplateKey(input: ScaffoldRuntimeInput): string {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i plan to refactor this in a future PR. We're going to want some of these parameters to determine the asset templates to render from, and some of them to be rendered into it with handlebars. However, this felt like the smallest change I could make to keep it functional with the new interface.

This PR is intended to focus on aligning the handlers with what we want, then we work backwards from there to implement the functionality we need to support it.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What makes this complexity necessary at this stage? Do we expect more than a handful of templates?

@Hweinstock
Hweinstock marked this pull request as ready for review August 24, 2026 22:37
@github-actions github-actions Bot added the size/l PR size: L label Aug 25, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@notgitika notgitika left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still reviewing the manager and templates files in a couple mins

Comment thread src/handlers/project/types.ts Outdated

/** Set of flags needed to scaffold a new Runtime-based agent **/
export const ScaffoldRuntimeInputSchema = z.object({
runtimeName: z.string().min(1),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe not related to this PR but if we are only checking if it is a string, is "../MyAgent" a valid runtime name? it would scaffold cold into <cwd>/.. outside the project then right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good question! my understanding is this case is handled for the runtime case in the schema itself, so when the write fails, the scaffolding rollback, but we don't have the same on the create command, so its currently possible to do this already.

runtime schema:

export const AgentNameSchema = z
.string()
.min(1, "Name is required")
.max(48)
.regex(
/^[a-zA-Z][a-zA-Z0-9_]{0,47}$/,
"Must begin with a letter and contain only alphanumeric characters and underscores (max 48 chars)",
);

To allow us to fail earlier and fix the create case, we can validate the same regex we validate in the schema here.

Comment on lines +119 to +131
await expect(
run([
"create",
"--name",
"MyAgent",
"--template",
"hello-world-python",
"--build",
"Container",
]),
).rejects.toThrow(/--template and --build are mutually exclusive/);
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

just wanted to confirm is our vision that we can probably add certain build time env vars into templates? so I can do like hello-world-python[no-memory]
or do we just reject that idea altogether?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my implementation here is based on the old CLI. my understanding from our conversation yesterday was that we want to mirror existing behavior, before adding new functionality. Hopefully we get a chance to come back and make this more flexible.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sounds good, we can revisit this later

"model provider for the scaffolded runtime code",
z.enum(["Bedrock"]).optional(),
),
flag(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

api-key is still not supported fully yet right? like it gets resolved but nothing reads it so it is dropped (assuming its since we only have bedrock for now)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes exactly. I put it there so that its wired up in the handler once we're ready, but there is no way to provide it.

Let me add some validation to reject this if we pass bedrock to make this more explicit.

"model-provider",
"api-key",
"memory",
"runtime-name",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wait so is runtime-name also mutually exclusive? I cant have "mydemoagent" as my runtime name with the template? seems like we are forcing the user too much here folks might want custom runtime name but the basic hello world scaffolding in it.

pulling it out of this list also gives you somewhere to hang the codeLocation fix.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I think I agree we should allow this to be customized, but our templates are not flexible enough to support this yet. The follow-up #2099 refactors the templates to add this functionality which should allow us to allow overrides like this.

},
});

function parseScaffoldRuntimeInput(input: Record<string, unknown>) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if i miss a flag, it would surface the raw Zod error.

for eg: create --name MyAgent --runtime-name foo prints
Invalid input: expected "none" → at framework

it points users to internal camelCase field paths rather than the --kebab flags they typed. can we check for the missing flags up front? or map it back to flag names

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be polished in follow up tbh

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good catch. I think it might make sense to circle back here, because this definitely isn't the only case of ugly error messages and I think we should establish some consistent standards.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't these kinds of errors get thrown before the handler itself runs? The framework should handle the validations of the given flags assuming they're populated.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Most of them yes, but I think the referenced message is coming from https://github.com/Hweinstock/agentcore-cli/blob/667fb0e60f750d4bed85ffb8c1fc790053375e69/src/handlers/project/create/index.ts#L117-L121 which happens after the flags are parsed and is part of a shared validation between this and the create handler for the scaffolding flags.

We could get rid of this if we share the flags themselves rather than a separate schema, but originally wanted to keep the flags explicit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nice!

Comment thread src/core/project/templates.ts Outdated

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is hardcoded but line 103 now writes the assets to app/${input.runtimeName}.

those are thes ame when runtimeName is hello-world, which is true for the presets but not for the custom flags path. I would say this is a blocker for this PR

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this is a hack to get the same behavior. let me be consistent with the hardcoding and properly remove it in the follow-up.

@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 25, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 25, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
@github-actions github-actions Bot added size/l PR size: L and removed size/l PR size: L labels Aug 25, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
@agentcore-devx-automation

Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label Aug 25, 2026
memory: z.enum(["none"]),
})
.refine(({ modelProvider, apiKey }) => !(modelProvider === "Bedrock" && apiKey !== undefined), {
message: "API keys are not compatible with Bedrock model providers",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noice

build: "CodeZip",
entrypoint: "main.py",
codeLocation: "app/hello-world",
codeLocation: "app/hello_world",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😭 I forgot - is not supported in runtime

@notgitika
notgitika self-requested a review August 25, 2026 21:21

@notgitika notgitika left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great to me!

const isCustom = presentScaffoldingFlags.length > 0;

const source = new SourceResolver({ stdin: config.io.stdin });
const apiKey = await source.resolveSecret("api-key", flags["api-key"]);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this hang if the api-key param isn't passed? api-key is required only for non-Bedrock model providers, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it handles the undefined case internally https://github.com/Hweinstock/agentcore-cli/blob/667fb0e60f750d4bed85ffb8c1fc790053375e69/src/io/source.ts#L62.

And yeah exactly, we only support bedrock atm so this is effectively a placeholder.

@AlexanderRichey AlexanderRichey left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. Left a couple questions that can be addressed in a follow up if necessary.

@Hweinstock
Hweinstock merged commit f1a651c into aws:refactor Aug 26, 2026
19 of 32 checks passed
@Hweinstock
Hweinstock deleted the refactor-templates branch August 26, 2026 01:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants