-
Notifications
You must be signed in to change notification settings - Fork 110
[Sherpa] Add pre-packaged skills with persistence and subagent config for SMAI spaces #1143
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
fda6bed
ac0625c
17b0a07
b55c719
5f6b4cb
db890cf
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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": [ | ||
| "@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 | ||
| } | ||
| 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 |
| 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" | ||
| } | ||
| ] |
| 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." |
| 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 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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 | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
|
|
||
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(ingore this already fixed)