Skip to content
Open
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
5 changes: 3 additions & 2 deletions awscli/customizations/agenttoolkit/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ def _install_default_skills(self, selected_agents, client, yes=False):
uni_print(f' Found: {names}\n', self._stream)

if not yes and not yes_no_choice(
f'\nInstall {len(default_skills)} default AWS skills? [Y/n]: '
f'\nInstall {len(default_skills)} default AWS skills? [Y/n]: ',
default=True,
):
return

Expand Down Expand Up @@ -196,7 +197,7 @@ def _install_default_skills(self, selected_agents, client, yes=False):

def _configure_mcp(self, agents, yes=False):
if not yes and not yes_no_choice(
'\nConfigure AWS MCP server connection? [Y/n]: '
'\nConfigure AWS MCP server connection? [Y/n]: ', default=True
):
return

Expand Down
2 changes: 2 additions & 0 deletions awscli/customizations/agenttoolkit/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

LOG = logging.getLogger(__name__)
MAX_UNCOMPRESSED_SIZE = 10 * 1024 * 1024 # 10 MB
AGENT_TOOLKIT_REGION = 'us-east-1'

NONPROD_ACCESS_TOKEN_HEADER = 'x-nonprod-access-token'
NONPROD_ACCESS_TOKEN_ENV_VAR = 'NONPROD_ACCESS_TOKEN_HEADER'
Expand Down Expand Up @@ -70,6 +71,7 @@ def create_client(session, parsed_globals):
session,
'agenttoolkit',
parsed_globals,
overrides={'region_name': AGENT_TOOLKIT_REGION},
)


Expand Down
5 changes: 4 additions & 1 deletion awscli/customizations/prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@
from awscli.utils import is_stdin_a_tty


def yes_no_choice(prompt):
def yes_no_choice(prompt, default=None):
"""
Prompts the user to answer a yes/no question.
Continually re-prompts for invalid selections.

:param prompt: Prompt text.
:param default: Optional boolean returned when the response is empty.
:returns: True for yes, False for no.
"""
while True:
response = compat_input(prompt)

if response == '' and default is not None:
return default
if response.lower() in ('y', 'yes'):
return True
elif response.lower() in ('n', 'no'):
Expand Down
46 changes: 46 additions & 0 deletions tests/unit/customizations/agenttoolkit/test_configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from unittest.mock import MagicMock, patch

import pytest
from botocore.exceptions import NoRegionError

from awscli.customizations.agenttoolkit.agents import AgentConfig
from awscli.customizations.agenttoolkit.configure import (
Expand Down Expand Up @@ -92,6 +93,51 @@ def test_no_agents_detected_raises_error(tmp_path):
_run(configs)


def test_skill_install_continues_without_configured_region(tmp_path):
configs = _make_agent_configs(tmp_path, count=1)
zip_bytes, checksum = make_skill_zip()
client = _make_client(skills=[{'name': 'aws-serverless'}])
session = make_session()

def create_client(service_name, region_name=None, **kwargs):
if region_name is None:
raise NoRegionError()
return client

session.create_client.side_effect = create_client
stream = StringIO()
cmd = ConfigureAgentToolkitCommand(
session, stream=stream, agent_configs=configs
)
parsed_args = MagicMock()
parsed_args.yes = False

with (
patch(
'awscli.customizations.agenttoolkit.configure.multiselect_choice',
side_effect=lambda msg, items, **kw: items,
),
patch(
'awscli.customizations.agenttoolkit.configure.yes_no_choice',
return_value=True,
),
patch(
'awscli.customizations.agenttoolkit.configure.get_skill_download',
return_value=(zip_bytes, checksum, 'v1'),
),
):
rc = cmd._run_main(parsed_args, {})

assert rc == 0
session.create_client.assert_called_once_with(
'agenttoolkit', region_name='us-east-1'
)
skill_path = (
tmp_path / '.agent-0' / 'skills' / 'aws-serverless' / 'SKILL.md'
)
assert skill_path.exists()


def test_detection_output(tmp_path):
configs = _make_agent_configs(tmp_path, count=1)
configs.append(
Expand Down
24 changes: 24 additions & 0 deletions tests/unit/customizations/test_prompts.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"). You
# may not use this file except in compliance with the License. A copy of
# the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "license" file accompanying this file. This file is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
# ANY KIND, either express or implied. See the License for the specific
# language governing permissions and limitations under the License.
from unittest.mock import patch

from awscli.customizations.prompts import yes_no_choice


def test_enter_accepts_yes_default():
with patch(
'awscli.customizations.prompts.compat_input', return_value=''
) as input_mock:
assert yes_no_choice('Continue? [Y/n]: ', default=True)

input_mock.assert_called_once_with('Continue? [Y/n]: ')