deepagents 1.7.3 → 1.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +113 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +50 -8
- package/dist/index.d.ts +51 -9
- package/dist/index.js +116 -20
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1856,6 +1856,7 @@ function createMemoryMiddleware(options) {
|
|
|
1856
1856
|
const MAX_SKILL_FILE_SIZE = 10 * 1024 * 1024;
|
|
1857
1857
|
const MAX_SKILL_NAME_LENGTH = 64;
|
|
1858
1858
|
const MAX_SKILL_DESCRIPTION_LENGTH = 1024;
|
|
1859
|
+
const MAX_SKILL_COMPATIBILITY_LENGTH = 500;
|
|
1859
1860
|
/**
|
|
1860
1861
|
* Zod schema for a single skill metadata entry.
|
|
1861
1862
|
*/
|
|
@@ -1943,6 +1944,22 @@ Remember: Skills are tools to make you more capable and consistent. When in doub
|
|
|
1943
1944
|
`;
|
|
1944
1945
|
/**
|
|
1945
1946
|
* Validate skill name per Agent Skills specification.
|
|
1947
|
+
*
|
|
1948
|
+
* Constraints per Agent Skills specification:
|
|
1949
|
+
*
|
|
1950
|
+
* - 1-64 characters
|
|
1951
|
+
* - Unicode lowercase alphanumeric and hyphens only (`a-z` and `-`).
|
|
1952
|
+
* - Must not start or end with `-`
|
|
1953
|
+
* - Must not contain consecutive `--`
|
|
1954
|
+
* - Must match the parent directory name containing the `SKILL.md` file
|
|
1955
|
+
*
|
|
1956
|
+
* Unicode lowercase alphanumeric means any lowercase or decimal digit, which
|
|
1957
|
+
* covers accented Latin characters (e.g., `'café'`, `'über-tool'`) and other
|
|
1958
|
+
* scripts.
|
|
1959
|
+
*
|
|
1960
|
+
* @param name - The skill name from YAML frontmatter
|
|
1961
|
+
* @param directoryName - The parent directory name
|
|
1962
|
+
* @returns `{ valid, error }` tuple. Error is empty string if valid.
|
|
1946
1963
|
*/
|
|
1947
1964
|
function validateSkillName$1(name, directoryName) {
|
|
1948
1965
|
if (!name) return {
|
|
@@ -1953,10 +1970,18 @@ function validateSkillName$1(name, directoryName) {
|
|
|
1953
1970
|
valid: false,
|
|
1954
1971
|
error: "name exceeds 64 characters"
|
|
1955
1972
|
};
|
|
1956
|
-
if (
|
|
1973
|
+
if (name.startsWith("-") || name.endsWith("-") || name.includes("--")) return {
|
|
1957
1974
|
valid: false,
|
|
1958
1975
|
error: "name must be lowercase alphanumeric with single hyphens only"
|
|
1959
1976
|
};
|
|
1977
|
+
for (const c of name) {
|
|
1978
|
+
if (c === "-") continue;
|
|
1979
|
+
if (/\p{Ll}/u.test(c) || /\p{Nd}/u.test(c)) continue;
|
|
1980
|
+
return {
|
|
1981
|
+
valid: false,
|
|
1982
|
+
error: "name must be lowercase alphanumeric with single hyphens only"
|
|
1983
|
+
};
|
|
1984
|
+
}
|
|
1960
1985
|
if (name !== directoryName) return {
|
|
1961
1986
|
valid: false,
|
|
1962
1987
|
error: `name '${name}' must match directory name '${directoryName}'`
|
|
@@ -1967,7 +1992,52 @@ function validateSkillName$1(name, directoryName) {
|
|
|
1967
1992
|
};
|
|
1968
1993
|
}
|
|
1969
1994
|
/**
|
|
1970
|
-
*
|
|
1995
|
+
* Validate and normalize the metadata field from YAML frontmatter.
|
|
1996
|
+
*
|
|
1997
|
+
* YAML parsing can return any type for the `metadata` key. This ensures the
|
|
1998
|
+
* value in {@link SkillMetadata} is always a `Record<string, string>` by
|
|
1999
|
+
* coercing via `String()` and rejecting non-object inputs.
|
|
2000
|
+
*
|
|
2001
|
+
* @param raw - Raw value from `frontmatterData.metadata`.
|
|
2002
|
+
* @param skillPath - Path to the `SKILL.md` file (for warning messages).
|
|
2003
|
+
* @returns A validated `Record<string, string>`.
|
|
2004
|
+
*/
|
|
2005
|
+
function validateMetadata(raw, skillPath) {
|
|
2006
|
+
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
2007
|
+
if (raw) console.warn(`Ignoring non-object metadata in ${skillPath} (got ${typeof raw})`);
|
|
2008
|
+
return {};
|
|
2009
|
+
}
|
|
2010
|
+
const result = {};
|
|
2011
|
+
for (const [k, v] of Object.entries(raw)) result[String(k)] = String(v);
|
|
2012
|
+
return result;
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* Build a parenthetical annotation string from optional skill fields.
|
|
2016
|
+
*
|
|
2017
|
+
* Combines license and compatibility into a comma-separated string for
|
|
2018
|
+
* display in the system prompt skill listing.
|
|
2019
|
+
*
|
|
2020
|
+
* @param skill - Skill metadata to extract annotations from.
|
|
2021
|
+
* @returns Annotation string like `'License: MIT, Compatibility: Python 3.10+'`,
|
|
2022
|
+
* or empty string if neither field is set.
|
|
2023
|
+
*/
|
|
2024
|
+
function formatSkillAnnotations(skill) {
|
|
2025
|
+
const parts = [];
|
|
2026
|
+
if (skill.license) parts.push(`License: ${skill.license}`);
|
|
2027
|
+
if (skill.compatibility) parts.push(`Compatibility: ${skill.compatibility}`);
|
|
2028
|
+
return parts.join(", ");
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Parse YAML frontmatter from `SKILL.md` content.
|
|
2032
|
+
*
|
|
2033
|
+
* Extracts metadata per Agent Skills specification from YAML frontmatter
|
|
2034
|
+
* delimited by `---` markers at the start of the content.
|
|
2035
|
+
*
|
|
2036
|
+
* @param content - Content of the `SKILL.md` file
|
|
2037
|
+
* @param skillPath - Path to the `SKILL.md` file (for error messages and metadata)
|
|
2038
|
+
* @param directoryName - Name of the parent directory containing the skill
|
|
2039
|
+
* @returns `SkillMetadata` if parsing succeeds, `null` if parsing fails or
|
|
2040
|
+
* validation errors occur
|
|
1971
2041
|
*/
|
|
1972
2042
|
function parseSkillMetadataFromContent(content, skillPath, directoryName) {
|
|
1973
2043
|
if (content.length > MAX_SKILL_FILE_SIZE) {
|
|
@@ -1991,28 +2061,36 @@ function parseSkillMetadataFromContent(content, skillPath, directoryName) {
|
|
|
1991
2061
|
console.warn(`Skipping ${skillPath}: frontmatter is not a mapping`);
|
|
1992
2062
|
return null;
|
|
1993
2063
|
}
|
|
1994
|
-
const name = frontmatterData.name;
|
|
1995
|
-
const description = frontmatterData.description;
|
|
2064
|
+
const name = String(frontmatterData.name ?? "").trim();
|
|
2065
|
+
const description = String(frontmatterData.description ?? "").trim();
|
|
1996
2066
|
if (!name || !description) {
|
|
1997
2067
|
console.warn(`Skipping ${skillPath}: missing required 'name' or 'description'`);
|
|
1998
2068
|
return null;
|
|
1999
2069
|
}
|
|
2000
|
-
const validation = validateSkillName$1(
|
|
2070
|
+
const validation = validateSkillName$1(name, directoryName);
|
|
2001
2071
|
if (!validation.valid) console.warn(`Skill '${name}' in ${skillPath} does not follow Agent Skills specification: ${validation.error}. Consider renaming for spec compliance.`);
|
|
2002
|
-
let descriptionStr =
|
|
2072
|
+
let descriptionStr = description;
|
|
2003
2073
|
if (descriptionStr.length > MAX_SKILL_DESCRIPTION_LENGTH) {
|
|
2004
2074
|
console.warn(`Description exceeds ${MAX_SKILL_DESCRIPTION_LENGTH} characters in ${skillPath}, truncating`);
|
|
2005
2075
|
descriptionStr = descriptionStr.slice(0, MAX_SKILL_DESCRIPTION_LENGTH);
|
|
2006
2076
|
}
|
|
2007
|
-
const
|
|
2008
|
-
|
|
2077
|
+
const rawTools = frontmatterData["allowed-tools"];
|
|
2078
|
+
let allowedTools;
|
|
2079
|
+
if (rawTools) if (Array.isArray(rawTools)) allowedTools = rawTools.map((t) => String(t).trim()).filter(Boolean);
|
|
2080
|
+
else allowedTools = String(rawTools).split(/\s+/).filter(Boolean);
|
|
2081
|
+
else allowedTools = [];
|
|
2082
|
+
let compatibilityStr = String(frontmatterData.compatibility ?? "").trim() || null;
|
|
2083
|
+
if (compatibilityStr && compatibilityStr.length > MAX_SKILL_COMPATIBILITY_LENGTH) {
|
|
2084
|
+
console.warn(`Compatibility exceeds ${MAX_SKILL_COMPATIBILITY_LENGTH} characters in ${skillPath}, truncating`);
|
|
2085
|
+
compatibilityStr = compatibilityStr.slice(0, MAX_SKILL_COMPATIBILITY_LENGTH);
|
|
2086
|
+
}
|
|
2009
2087
|
return {
|
|
2010
|
-
name
|
|
2088
|
+
name,
|
|
2011
2089
|
description: descriptionStr,
|
|
2012
2090
|
path: skillPath,
|
|
2013
|
-
metadata: frontmatterData.metadata
|
|
2014
|
-
license:
|
|
2015
|
-
compatibility:
|
|
2091
|
+
metadata: validateMetadata(frontmatterData.metadata ?? {}, skillPath),
|
|
2092
|
+
license: String(frontmatterData.license ?? "").trim() || null,
|
|
2093
|
+
compatibility: compatibilityStr,
|
|
2016
2094
|
allowedTools
|
|
2017
2095
|
};
|
|
2018
2096
|
}
|
|
@@ -2076,7 +2154,10 @@ function formatSkillsList(skills, sources) {
|
|
|
2076
2154
|
if (skills.length === 0) return `(No skills available yet. You can create skills in ${sources.map((s) => `\`${s}\``).join(" or ")})`;
|
|
2077
2155
|
const lines = [];
|
|
2078
2156
|
for (const skill of skills) {
|
|
2079
|
-
|
|
2157
|
+
const annotations = formatSkillAnnotations(skill);
|
|
2158
|
+
let descLine = `- **${skill.name}**: ${skill.description}`;
|
|
2159
|
+
if (annotations) descLine += ` (${annotations})`;
|
|
2160
|
+
lines.push(descLine);
|
|
2080
2161
|
if (skill.allowedTools && skill.allowedTools.length > 0) lines.push(` → Allowed tools: ${skill.allowedTools.join(", ")}`);
|
|
2081
2162
|
lines.push(` → Read \`${skill.path}\` for full instructions`);
|
|
2082
2163
|
}
|
|
@@ -2136,11 +2217,10 @@ function createSkillsMiddleware(options) {
|
|
|
2136
2217
|
const skillsLocations = formatSkillsLocations(sources);
|
|
2137
2218
|
const skillsList = formatSkillsList(skillsMetadata, sources);
|
|
2138
2219
|
const skillsSection = SKILLS_SYSTEM_PROMPT.replace("{skills_locations}", skillsLocations).replace("{skills_list}", skillsList);
|
|
2139
|
-
const
|
|
2140
|
-
const newSystemPrompt = currentSystemPrompt ? `${currentSystemPrompt}\n\n${skillsSection}` : skillsSection;
|
|
2220
|
+
const newSystemMessage = request.systemMessage.concat(skillsSection);
|
|
2141
2221
|
return handler({
|
|
2142
2222
|
...request,
|
|
2143
|
-
|
|
2223
|
+
systemMessage: newSystemMessage
|
|
2144
2224
|
});
|
|
2145
2225
|
}
|
|
2146
2226
|
});
|
|
@@ -2198,9 +2278,25 @@ function createSkillsMiddleware(options) {
|
|
|
2198
2278
|
* from `langchain` directly.
|
|
2199
2279
|
*/
|
|
2200
2280
|
/**
|
|
2281
|
+
* Zod schema for a summarization event that tracks what was summarized and
|
|
2282
|
+
* where the cutoff is.
|
|
2283
|
+
*
|
|
2284
|
+
* Instead of rewriting LangGraph state with `RemoveMessage(REMOVE_ALL_MESSAGES)`,
|
|
2285
|
+
* the middleware stores this event and uses it to reconstruct the effective message
|
|
2286
|
+
* list on subsequent calls.
|
|
2287
|
+
*/
|
|
2288
|
+
const SummarizationEventSchema = zod.z.object({
|
|
2289
|
+
cutoffIndex: zod.z.number(),
|
|
2290
|
+
summaryMessage: zod.z.instanceof(langchain.HumanMessage),
|
|
2291
|
+
filePath: zod.z.string().nullable()
|
|
2292
|
+
});
|
|
2293
|
+
/**
|
|
2201
2294
|
* State schema for summarization middleware.
|
|
2202
2295
|
*/
|
|
2203
|
-
const SummarizationStateSchema = zod.z.object({
|
|
2296
|
+
const SummarizationStateSchema = zod.z.object({
|
|
2297
|
+
_summarizationSessionId: zod.z.string().optional(),
|
|
2298
|
+
_summarizationEvent: SummarizationEventSchema.optional()
|
|
2299
|
+
});
|
|
2204
2300
|
|
|
2205
2301
|
//#endregion
|
|
2206
2302
|
//#region src/backends/store.ts
|