[PR #211] [MERGED] fix(skills): improve skills middleware input validation and add annotations #211

Closed
opened 2026-02-16 06:17:27 -05:00 by yindo · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/langchain-ai/deepagentsjs/pull/211
Author: @hntrl
Created: 2/9/2026
Status: Merged
Merged: 2/10/2026
Merged by: @hntrl

Base: mainHead: hunter/skills-hardening


📝 Commits (4)

📊 Changes

5 files changed (+629 additions, -85 deletions)

View changed files

.changeset/skills-middleware-robustness.md (+11 -0)
📝 .codespellignore (+3 -1)
.pr-description.md (+0 -51)
📝 libs/deepagents/src/middleware/skills.test.ts (+432 -0)
📝 libs/deepagents/src/middleware/skills.ts (+183 -33)

📄 Description

Summary

Port of Python PR #1189 to the JS skills middleware. Improves input validation robustness and adds license/compatibility annotations to the system prompt skill listing.

Changes

libs/deepagents/src/middleware/skills.ts

  • MAX_SKILL_COMPATIBILITY_LENGTH — new constant (500) for enforcing compatibility field length
  • SkillMetadata JSDoc — updated with detailed Agent Skills spec constraints for all fields
  • validateSkillName — replaced ASCII-only regex with character-by-character Unicode validation (\p{Ll}, \p{Nd}); now accepts accented Latin names (e.g. café, über-tool) while rejecting CJK, emoji, uppercase
  • validateMetadata — new exported helper ensuring metadata is always Record<string, string> (rejects non-objects, coerces values via String())
  • formatSkillAnnotations — new exported helper building (License: ..., Compatibility: ...) annotation strings
  • parseSkillMetadataFromContent — hardened with String().trim() coercion for name/description, YAML list + multi-space support for allowed-tools, String() coercion for license, compatibility length truncation, validateMetadata() for metadata
  • formatSkillsList — now appends license/compatibility annotations to skill description lines

libs/deepagents/src/middleware/skills.test.ts

Added 27 new unit tests across 5 describe blocks:

  • validateSkillName — Unicode accept/reject, edge cases (11 tests)
  • parseSkillMetadataFromContent — whitespace rejection, YAML lists, field coercion, compatibility truncation, metadata handling (10 tests)
  • validateMetadata — non-dict, list, null, undefined, coercion, passthrough (6 tests)
  • formatSkillAnnotations — both fields, each alone, neither (4 tests)
  • formatSkillsList with annotations — full annotations, license-only, compatibility-only, no annotations (4 tests)

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/langchain-ai/deepagentsjs/pull/211 **Author:** [@hntrl](https://github.com/hntrl) **Created:** 2/9/2026 **Status:** ✅ Merged **Merged:** 2/10/2026 **Merged by:** [@hntrl](https://github.com/hntrl) **Base:** `main` ← **Head:** `hunter/skills-hardening` --- ### 📝 Commits (4) - [`d94c75b`](https://github.com/langchain-ai/deepagentsjs/commit/d94c75b84dc638c20b1c2e0135fcded63d2a37b1) fix(skills): improve skills middleware input validation and add annotations - [`15863a1`](https://github.com/langchain-ai/deepagentsjs/commit/15863a1d019ecdd22e3cfa87bf04fd379645d99a) cr - [`de560e2`](https://github.com/langchain-ai/deepagentsjs/commit/de560e238c1d31dfa09775af4cf3a71d792ae765) cr - [`9c056a0`](https://github.com/langchain-ai/deepagentsjs/commit/9c056a0c8349cdfd552ede0c69f1e996f7f8bbc6) cr ### 📊 Changes **5 files changed** (+629 additions, -85 deletions) <details> <summary>View changed files</summary> ➕ `.changeset/skills-middleware-robustness.md` (+11 -0) 📝 `.codespellignore` (+3 -1) ➖ `.pr-description.md` (+0 -51) 📝 `libs/deepagents/src/middleware/skills.test.ts` (+432 -0) 📝 `libs/deepagents/src/middleware/skills.ts` (+183 -33) </details> ### 📄 Description ## Summary Port of Python [PR #1189](https://github.com/langchain-ai/deepagents/pull/1189) to the JS skills middleware. Improves input validation robustness and adds license/compatibility annotations to the system prompt skill listing. ## Changes ### `libs/deepagents/src/middleware/skills.ts` - **`MAX_SKILL_COMPATIBILITY_LENGTH`** — new constant (500) for enforcing compatibility field length - **`SkillMetadata` JSDoc** — updated with detailed Agent Skills spec constraints for all fields - **`validateSkillName`** — replaced ASCII-only regex with character-by-character Unicode validation (`\p{Ll}`, `\p{Nd}`); now accepts accented Latin names (e.g. `café`, `über-tool`) while rejecting CJK, emoji, uppercase - **`validateMetadata`** — new exported helper ensuring metadata is always `Record<string, string>` (rejects non-objects, coerces values via `String()`) - **`formatSkillAnnotations`** — new exported helper building `(License: ..., Compatibility: ...)` annotation strings - **`parseSkillMetadataFromContent`** — hardened with `String().trim()` coercion for name/description, YAML list + multi-space support for `allowed-tools`, `String()` coercion for license, compatibility length truncation, `validateMetadata()` for metadata - **`formatSkillsList`** — now appends license/compatibility annotations to skill description lines ### `libs/deepagents/src/middleware/skills.test.ts` Added 27 new unit tests across 5 describe blocks: - `validateSkillName` — Unicode accept/reject, edge cases (11 tests) - `parseSkillMetadataFromContent` — whitespace rejection, YAML lists, field coercion, compatibility truncation, metadata handling (10 tests) - `validateMetadata` — non-dict, list, null, undefined, coercion, passthrough (6 tests) - `formatSkillAnnotations` — both fields, each alone, neither (4 tests) - `formatSkillsList with annotations` — full annotations, license-only, compatibility-only, no annotations (4 tests) --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
yindo added the pull-request label 2026-02-16 06:17:27 -05:00
yindo closed this issue 2026-02-16 06:17:27 -05:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: langchain-ai/deepagentsjs#211