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
2 changes: 2 additions & 0 deletions template/v4/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ RUN apt-get update && apt-get upgrade -y && \
COPY dirs/ ${DIRECTORY_TREE_STAGE_DIR}/
RUN rsync -a ${DIRECTORY_TREE_STAGE_DIR}/ / && \
rm -rf ${DIRECTORY_TREE_STAGE_DIR} && \
# Clone skills from manifest config (must run after COPY dirs/ + rsync which provides skills-manifest.json)
bash /etc/sagemaker/skills/clone_skills.sh && \
# CodeEditor - download the extensions
mkdir -p /etc/code-editor/extensions /etc/code-editor/extensions-sagemaker-ui && \
while IFS= read -r url || [ -n "$url" ]; do \
Expand Down
21 changes: 21 additions & 0 deletions template/v4/dirs/etc/sagemaker/sagemaker-default-agent.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "sagemaker_default",
"description": "SageMaker AI assistant with pre-installed skills for model customization, evaluation, deployment, and HyperPod operations.",
"prompt": "You are a specialized AI assistant for Amazon SageMaker Studio. You can help with general purpose tasks, but you also have expertise in SageMaker workflows and skills.",
"mcpServers": {},
"tools": ["*"],
"toolAliases": {},
"allowedTools": [
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.

needs update based on what we have in jupyter MCP

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.

(ingore this already fixed)

"@jupyter_mcp_server/read_notebook",
"@jupyter_mcp_server/read_notebook_cells",
"@jupyter_mcp_server/open_file",
"@jupyter_mcp_server/select_cell",
"@jupyter_mcp_server/get_active_notebook",
"@jupyter_mcp_server/get_active_cell_id",
"@jupyter_mcp_server/get_open_documents"
],
"resources": ["skill://.kiro/skills/**/SKILL.md"],
"hooks": {},
"toolsSettings": {},
"includeMcpJson": true
}
14 changes: 14 additions & 0 deletions template/v4/dirs/etc/sagemaker/skills/clone_skills.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/bash
# Clones skills from repos listed in skills-manifest.json during Docker build.
set -eu

MANIFEST="/etc/sagemaker/skills/skills-manifest.json"
DEST="/etc/sagemaker/skills"

jq -c '.[]' "$MANIFEST" | while read -r entry; do
repo=$(echo "$entry" | jq -r '.repo')
spath=$(echo "$entry" | jq -r '.path')
git clone --depth 1 "$repo" /tmp/skill-repo
cp -r "/tmp/skill-repo/$spath"/* "$DEST"/
rm -rf /tmp/skill-repo
done
6 changes: 6 additions & 0 deletions template/v4/dirs/etc/sagemaker/skills/skills-manifest.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[
{
"repo": "https://github.com/awslabs/agent-plugins.git",
"path": "plugins/sagemaker-ai/skills"
}
]
72 changes: 72 additions & 0 deletions template/v4/dirs/etc/sagemaker/skills/sync_skills.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/bin/bash
# Syncs pre-packaged SageMaker skills from image to user's EBS.
set -eu

IMAGE_SKILLS_DIR="/etc/sagemaker/skills"
EBS_SKILLS_DIR="$HOME/.agent/skills"
LOCK_FILE="$EBS_SKILLS_DIR/.sagemaker-lock"

# Agent targets to symlink skills into (add new agents here)
AGENT_SKILLS_DIRS=("$HOME/.kiro/skills")

compute_checksum() {
(cd "$1" && find . -type f -print0 | sort -z | xargs -0 sha256sum | sha256sum | awk '{print $1}')
}

get_locked_checksum() {
[ -f "$LOCK_FILE" ] && jq -r --arg s "$1" '.skills[$s].checksum // empty' "$LOCK_FILE" 2>/dev/null
}

set_locked_checksum() {
[ -f "$LOCK_FILE" ] || echo '{"skills":{}}' > "$LOCK_FILE"
jq --arg s "$1" --arg c "$2" '.skills[$s].checksum = $c' "$LOCK_FILE" > "$LOCK_FILE.tmp"
mv "$LOCK_FILE.tmp" "$LOCK_FILE"
}

mkdir -p "$EBS_SKILLS_DIR"
for dir in "${AGENT_SKILLS_DIRS[@]}"; do mkdir -p "$dir"; done

if [ ! -d "$IMAGE_SKILLS_DIR" ]; then
echo "No bundled skills found at $IMAGE_SKILLS_DIR, skipping."
exit 0
fi

for skill_path in "$IMAGE_SKILLS_DIR"/*/; do
[ -d "$skill_path" ] || continue
skill_name=$(basename "$skill_path")
ebs_skill="$EBS_SKILLS_DIR/$skill_name"
image_checksum=$(compute_checksum "$skill_path")

if [ ! -d "$ebs_skill" ]; then
cp -r "$skill_path" "$ebs_skill"
set_locked_checksum "$skill_name" "$image_checksum"
echo "Installed skill '$skill_name'"
else
recorded_checksum=$(get_locked_checksum "$skill_name")
current_checksum=$(compute_checksum "$ebs_skill")

if [ "$current_checksum" = "$recorded_checksum" ]; then
if [ "$image_checksum" != "$recorded_checksum" ]; then
rm -rf "$ebs_skill"
cp -r "$skill_path" "$ebs_skill"
set_locked_checksum "$skill_name" "$image_checksum"
echo "Updated skill '$skill_name'"
else
echo "Skill '$skill_name' already current, skipping"
fi
else
echo "Skipping skill '$skill_name' — user modified"
fi
fi

# Create symlinks for all agent targets
for agent_dir in "${AGENT_SKILLS_DIRS[@]}"; do
link="$agent_dir/$skill_name"
if [ ! -e "$link" ]; then
ln -s "$ebs_skill" "$link"
echo "Created symlink $link -> $ebs_skill"
fi
done
done

echo "Skills sync complete."
23 changes: 23 additions & 0 deletions template/v4/dirs/etc/sagemaker/sync_agent.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/bin/bash
# Syncs agent config (subagent, default agent settings) for SMAI spaces.
set -eu

AGENT_CONFIG_SRC="/etc/sagemaker/sagemaker-default-agent.json"
AGENT_CONFIG_DST="$HOME/.kiro/agents/sagemaker-default-agent.json"
KIRO_CLI_SETTINGS="$HOME/.kiro/settings/cli.json"

# Install subagent config (always overwrite)
mkdir -p "$HOME/.kiro/agents"
cp "$AGENT_CONFIG_SRC" "$AGENT_CONFIG_DST"
echo "Installed agent config to $AGENT_CONFIG_DST"

# Set default agent only if user hasn't configured one
mkdir -p "$HOME/.kiro/settings"
if [ ! -f "$KIRO_CLI_SETTINGS" ]; then
echo '{"chat.defaultAgent":"sagemaker_default"}' > "$KIRO_CLI_SETTINGS"
echo "Created default agent settings"
elif ! jq -e '."chat.defaultAgent"' "$KIRO_CLI_SETTINGS" >/dev/null 2>&1; then
jq '. + {"chat.defaultAgent":"sagemaker_default"}' "$KIRO_CLI_SETTINGS" > "$KIRO_CLI_SETTINGS.tmp"
mv "$KIRO_CLI_SETTINGS.tmp" "$KIRO_CLI_SETTINGS"
echo "Added default agent to existing settings"
fi
11 changes: 11 additions & 0 deletions template/v4/dirs/usr/local/bin/start-jupyter-server
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ else
micromamba remove -y sagemaker-studio-dataengineering-sessions sagemaker-studio-dataengineering-extensions
# Disable SMUS-specific extensions
jupyter labextension disable sagemaker-data-explorer:plugin
# Disable old Q chat extension
jupyter labextension disable @amzn/amazon_sagemaker_jupyter_ai_q_developer
fi

# Setup skills and subagent for SMAI private spaces only
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.

we can do skills and subagent in shared spaces TBH. lets keep this. lets just turn off chat in shared spaces.

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.

OK for now though we can follow up on this

if [ -n "$SAGEMAKER_APP_TYPE_LOWERCASE" ] && [ "$SAGEMAKER_SPACE_TYPE_LOWERCASE" != "shared" ]; then
# Sync pre-packaged skills to EBS
bash /etc/sagemaker/skills/sync_skills.sh 2>&1 || echo "Warning: skills sync failed, continuing..."

# Sync agent config (subagent + default agent settings)
bash /etc/sagemaker/sync_agent.sh 2>&1 || echo "Warning: agent config sync failed, continuing..."
fi

# Enable S3AG plugin if TIP is enabled
Expand Down