deepagents 1.7.4 → 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.d.cts CHANGED
@@ -570,9 +570,11 @@ declare const TASK_SYSTEM_PROMPT = "## `task` (subagent spawner)\n\nYou have acc
570
570
  * Type definitions for pre-compiled agents.
571
571
  *
572
572
  * @typeParam TRunnable - The type of the runnable (ReactAgent or Runnable).
573
- * When using `createAgent`, this preserves the middleware types for type inference.
573
+ * When using `createAgent` or `createDeepAgent`, this preserves the middleware
574
+ * types for type inference. Uses `ReactAgent<any>` to accept agents with any
575
+ * type configuration (including DeepAgent instances).
574
576
  */
575
- interface CompiledSubAgent<TRunnable extends ReactAgent | Runnable = ReactAgent | Runnable> {
577
+ interface CompiledSubAgent<TRunnable extends ReactAgent<any> | Runnable = ReactAgent<any> | Runnable> {
576
578
  /** The name of the agent */
577
579
  name: string;
578
580
  /** The description of the agent */
@@ -893,19 +895,59 @@ declare const MAX_SKILL_DESCRIPTION_LENGTH = 1024;
893
895
  * Metadata for a skill per Agent Skills specification.
894
896
  */
895
897
  interface SkillMetadata$1 {
896
- /** Skill identifier (max 64 chars, lowercase alphanumeric and hyphens) */
898
+ /**
899
+ * Skill identifier.
900
+ *
901
+ * Constraints per Agent Skills specification:
902
+ *
903
+ * - 1-64 characters
904
+ * - Unicode lowercase alphanumeric and hyphens only (`a-z` and `-`).
905
+ * - Must not start or end with `-`
906
+ * - Must not contain consecutive `--`
907
+ * - Must match the parent directory name containing the `SKILL.md` file
908
+ */
897
909
  name: string;
898
- /** What the skill does (max 1024 chars) */
910
+ /**
911
+ * What the skill does.
912
+ *
913
+ * Constraints per Agent Skills specification:
914
+ *
915
+ * - 1-1024 characters
916
+ * - Should describe both what the skill does and when to use it
917
+ * - Should include specific keywords that help agents identify relevant tasks
918
+ */
899
919
  description: string;
900
920
  /** Path to the SKILL.md file in the backend */
901
921
  path: string;
902
- /** License name or reference to bundled license file */
922
+ /** License name or reference to bundled license file. */
903
923
  license?: string | null;
904
- /** Environment requirements (max 500 chars) */
924
+ /**
925
+ * Environment requirements.
926
+ *
927
+ * Constraints per Agent Skills specification:
928
+ *
929
+ * - 1-500 characters if provided
930
+ * - Should only be included if there are specific compatibility requirements
931
+ * - Can indicate intended product, required packages, etc.
932
+ */
905
933
  compatibility?: string | null;
906
- /** Arbitrary key-value mapping for additional metadata */
934
+ /**
935
+ * Arbitrary key-value mapping for additional metadata.
936
+ *
937
+ * Clients can use this to store additional properties not defined by the spec.
938
+ *
939
+ * It is recommended to keep key names unique to avoid conflicts.
940
+ */
907
941
  metadata?: Record<string, string>;
908
- /** List of pre-approved tools (experimental) */
942
+ /**
943
+ * Tool names the skill recommends using.
944
+ *
945
+ * Warning: this is experimental.
946
+ *
947
+ * Constraints per Agent Skills specification:
948
+ *
949
+ * - Space-delimited list of tool names
950
+ */
909
951
  allowedTools?: string[];
910
952
  }
911
953
  /**
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as langchain from "langchain";
2
- import { AgentMiddleware, AgentMiddleware as AgentMiddleware$1, AgentTypeConfig, InferMiddlewareStates, InterruptOnConfig, ReactAgent, ResponseFormat, ResponseFormatUndefined, StructuredTool, SystemMessage, ToolMessage } from "langchain";
2
+ import { AgentMiddleware, AgentMiddleware as AgentMiddleware$1, AgentTypeConfig, HumanMessage, InferMiddlewareStates, InterruptOnConfig, ReactAgent, ResponseFormat, ResponseFormatUndefined, StructuredTool, SystemMessage, ToolMessage } from "langchain";
3
3
  import { Runnable } from "@langchain/core/runnables";
4
4
  import * as _langchain_langgraph0 from "@langchain/langgraph";
5
5
  import { AnnotationRoot, Command, ReducedValue, StateSchema } from "@langchain/langgraph";
@@ -570,9 +570,11 @@ declare const TASK_SYSTEM_PROMPT = "## `task` (subagent spawner)\n\nYou have acc
570
570
  * Type definitions for pre-compiled agents.
571
571
  *
572
572
  * @typeParam TRunnable - The type of the runnable (ReactAgent or Runnable).
573
- * When using `createAgent`, this preserves the middleware types for type inference.
573
+ * When using `createAgent` or `createDeepAgent`, this preserves the middleware
574
+ * types for type inference. Uses `ReactAgent<any>` to accept agents with any
575
+ * type configuration (including DeepAgent instances).
574
576
  */
575
- interface CompiledSubAgent<TRunnable extends ReactAgent | Runnable = ReactAgent | Runnable> {
577
+ interface CompiledSubAgent<TRunnable extends ReactAgent<any> | Runnable = ReactAgent<any> | Runnable> {
576
578
  /** The name of the agent */
577
579
  name: string;
578
580
  /** The description of the agent */
@@ -893,19 +895,59 @@ declare const MAX_SKILL_DESCRIPTION_LENGTH = 1024;
893
895
  * Metadata for a skill per Agent Skills specification.
894
896
  */
895
897
  interface SkillMetadata$1 {
896
- /** Skill identifier (max 64 chars, lowercase alphanumeric and hyphens) */
898
+ /**
899
+ * Skill identifier.
900
+ *
901
+ * Constraints per Agent Skills specification:
902
+ *
903
+ * - 1-64 characters
904
+ * - Unicode lowercase alphanumeric and hyphens only (`a-z` and `-`).
905
+ * - Must not start or end with `-`
906
+ * - Must not contain consecutive `--`
907
+ * - Must match the parent directory name containing the `SKILL.md` file
908
+ */
897
909
  name: string;
898
- /** What the skill does (max 1024 chars) */
910
+ /**
911
+ * What the skill does.
912
+ *
913
+ * Constraints per Agent Skills specification:
914
+ *
915
+ * - 1-1024 characters
916
+ * - Should describe both what the skill does and when to use it
917
+ * - Should include specific keywords that help agents identify relevant tasks
918
+ */
899
919
  description: string;
900
920
  /** Path to the SKILL.md file in the backend */
901
921
  path: string;
902
- /** License name or reference to bundled license file */
922
+ /** License name or reference to bundled license file. */
903
923
  license?: string | null;
904
- /** Environment requirements (max 500 chars) */
924
+ /**
925
+ * Environment requirements.
926
+ *
927
+ * Constraints per Agent Skills specification:
928
+ *
929
+ * - 1-500 characters if provided
930
+ * - Should only be included if there are specific compatibility requirements
931
+ * - Can indicate intended product, required packages, etc.
932
+ */
905
933
  compatibility?: string | null;
906
- /** Arbitrary key-value mapping for additional metadata */
934
+ /**
935
+ * Arbitrary key-value mapping for additional metadata.
936
+ *
937
+ * Clients can use this to store additional properties not defined by the spec.
938
+ *
939
+ * It is recommended to keep key names unique to avoid conflicts.
940
+ */
907
941
  metadata?: Record<string, string>;
908
- /** List of pre-approved tools (experimental) */
942
+ /**
943
+ * Tool names the skill recommends using.
944
+ *
945
+ * Warning: this is experimental.
946
+ *
947
+ * Constraints per Agent Skills specification:
948
+ *
949
+ * - Space-delimited list of tool names
950
+ */
909
951
  allowedTools?: string[];
910
952
  }
911
953
  /**
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
- import { AIMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, createAgent, createMiddleware, humanInTheLoopMiddleware, summarizationMiddleware, todoListMiddleware, tool } from "langchain";
1
+ import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCachingMiddleware, createAgent, createMiddleware, humanInTheLoopMiddleware, summarizationMiddleware, todoListMiddleware, tool } from "langchain";
2
2
  import { Runnable } from "@langchain/core/runnables";
3
3
  import { Command, REMOVE_ALL_MESSAGES, ReducedValue, StateSchema, getCurrentTaskInput, isCommand } from "@langchain/langgraph";
4
4
  import { z } from "zod/v4";
5
5
  import micromatch from "micromatch";
6
6
  import { basename } from "path";
7
- import { HumanMessage, RemoveMessage } from "@langchain/core/messages";
7
+ import { HumanMessage as HumanMessage$1, RemoveMessage } from "@langchain/core/messages";
8
8
  import { z as z$1 } from "zod";
9
9
  import yaml from "yaml";
10
10
  import "uuid";
@@ -1403,7 +1403,7 @@ function createTaskTool(options) {
1403
1403
  }
1404
1404
  const subagent = subagentGraphs[subagent_type];
1405
1405
  const subagentState = filterStateForSubagent(getCurrentTaskInput());
1406
- subagentState.messages = [new HumanMessage({ content: description })];
1406
+ subagentState.messages = [new HumanMessage$1({ content: description })];
1407
1407
  const result = await subagent.invoke(subagentState, config);
1408
1408
  if (!config.toolCall?.id) throw new Error("Tool call ID is required for subagent invocation");
1409
1409
  return returnCommandWithStateUpdate(result, config.toolCall.id);
@@ -1821,6 +1821,7 @@ function createMemoryMiddleware(options) {
1821
1821
  const MAX_SKILL_FILE_SIZE = 10 * 1024 * 1024;
1822
1822
  const MAX_SKILL_NAME_LENGTH = 64;
1823
1823
  const MAX_SKILL_DESCRIPTION_LENGTH = 1024;
1824
+ const MAX_SKILL_COMPATIBILITY_LENGTH = 500;
1824
1825
  /**
1825
1826
  * Zod schema for a single skill metadata entry.
1826
1827
  */
@@ -1908,6 +1909,22 @@ Remember: Skills are tools to make you more capable and consistent. When in doub
1908
1909
  `;
1909
1910
  /**
1910
1911
  * Validate skill name per Agent Skills specification.
1912
+ *
1913
+ * Constraints per Agent Skills specification:
1914
+ *
1915
+ * - 1-64 characters
1916
+ * - Unicode lowercase alphanumeric and hyphens only (`a-z` and `-`).
1917
+ * - Must not start or end with `-`
1918
+ * - Must not contain consecutive `--`
1919
+ * - Must match the parent directory name containing the `SKILL.md` file
1920
+ *
1921
+ * Unicode lowercase alphanumeric means any lowercase or decimal digit, which
1922
+ * covers accented Latin characters (e.g., `'café'`, `'über-tool'`) and other
1923
+ * scripts.
1924
+ *
1925
+ * @param name - The skill name from YAML frontmatter
1926
+ * @param directoryName - The parent directory name
1927
+ * @returns `{ valid, error }` tuple. Error is empty string if valid.
1911
1928
  */
1912
1929
  function validateSkillName$1(name, directoryName) {
1913
1930
  if (!name) return {
@@ -1918,10 +1935,18 @@ function validateSkillName$1(name, directoryName) {
1918
1935
  valid: false,
1919
1936
  error: "name exceeds 64 characters"
1920
1937
  };
1921
- if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(name)) return {
1938
+ if (name.startsWith("-") || name.endsWith("-") || name.includes("--")) return {
1922
1939
  valid: false,
1923
1940
  error: "name must be lowercase alphanumeric with single hyphens only"
1924
1941
  };
1942
+ for (const c of name) {
1943
+ if (c === "-") continue;
1944
+ if (/\p{Ll}/u.test(c) || /\p{Nd}/u.test(c)) continue;
1945
+ return {
1946
+ valid: false,
1947
+ error: "name must be lowercase alphanumeric with single hyphens only"
1948
+ };
1949
+ }
1925
1950
  if (name !== directoryName) return {
1926
1951
  valid: false,
1927
1952
  error: `name '${name}' must match directory name '${directoryName}'`
@@ -1932,7 +1957,52 @@ function validateSkillName$1(name, directoryName) {
1932
1957
  };
1933
1958
  }
1934
1959
  /**
1935
- * Parse YAML frontmatter from SKILL.md content.
1960
+ * Validate and normalize the metadata field from YAML frontmatter.
1961
+ *
1962
+ * YAML parsing can return any type for the `metadata` key. This ensures the
1963
+ * value in {@link SkillMetadata} is always a `Record<string, string>` by
1964
+ * coercing via `String()` and rejecting non-object inputs.
1965
+ *
1966
+ * @param raw - Raw value from `frontmatterData.metadata`.
1967
+ * @param skillPath - Path to the `SKILL.md` file (for warning messages).
1968
+ * @returns A validated `Record<string, string>`.
1969
+ */
1970
+ function validateMetadata(raw, skillPath) {
1971
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
1972
+ if (raw) console.warn(`Ignoring non-object metadata in ${skillPath} (got ${typeof raw})`);
1973
+ return {};
1974
+ }
1975
+ const result = {};
1976
+ for (const [k, v] of Object.entries(raw)) result[String(k)] = String(v);
1977
+ return result;
1978
+ }
1979
+ /**
1980
+ * Build a parenthetical annotation string from optional skill fields.
1981
+ *
1982
+ * Combines license and compatibility into a comma-separated string for
1983
+ * display in the system prompt skill listing.
1984
+ *
1985
+ * @param skill - Skill metadata to extract annotations from.
1986
+ * @returns Annotation string like `'License: MIT, Compatibility: Python 3.10+'`,
1987
+ * or empty string if neither field is set.
1988
+ */
1989
+ function formatSkillAnnotations(skill) {
1990
+ const parts = [];
1991
+ if (skill.license) parts.push(`License: ${skill.license}`);
1992
+ if (skill.compatibility) parts.push(`Compatibility: ${skill.compatibility}`);
1993
+ return parts.join(", ");
1994
+ }
1995
+ /**
1996
+ * Parse YAML frontmatter from `SKILL.md` content.
1997
+ *
1998
+ * Extracts metadata per Agent Skills specification from YAML frontmatter
1999
+ * delimited by `---` markers at the start of the content.
2000
+ *
2001
+ * @param content - Content of the `SKILL.md` file
2002
+ * @param skillPath - Path to the `SKILL.md` file (for error messages and metadata)
2003
+ * @param directoryName - Name of the parent directory containing the skill
2004
+ * @returns `SkillMetadata` if parsing succeeds, `null` if parsing fails or
2005
+ * validation errors occur
1936
2006
  */
1937
2007
  function parseSkillMetadataFromContent(content, skillPath, directoryName) {
1938
2008
  if (content.length > MAX_SKILL_FILE_SIZE) {
@@ -1956,28 +2026,36 @@ function parseSkillMetadataFromContent(content, skillPath, directoryName) {
1956
2026
  console.warn(`Skipping ${skillPath}: frontmatter is not a mapping`);
1957
2027
  return null;
1958
2028
  }
1959
- const name = frontmatterData.name;
1960
- const description = frontmatterData.description;
2029
+ const name = String(frontmatterData.name ?? "").trim();
2030
+ const description = String(frontmatterData.description ?? "").trim();
1961
2031
  if (!name || !description) {
1962
2032
  console.warn(`Skipping ${skillPath}: missing required 'name' or 'description'`);
1963
2033
  return null;
1964
2034
  }
1965
- const validation = validateSkillName$1(String(name), directoryName);
2035
+ const validation = validateSkillName$1(name, directoryName);
1966
2036
  if (!validation.valid) console.warn(`Skill '${name}' in ${skillPath} does not follow Agent Skills specification: ${validation.error}. Consider renaming for spec compliance.`);
1967
- let descriptionStr = String(description).trim();
2037
+ let descriptionStr = description;
1968
2038
  if (descriptionStr.length > MAX_SKILL_DESCRIPTION_LENGTH) {
1969
2039
  console.warn(`Description exceeds ${MAX_SKILL_DESCRIPTION_LENGTH} characters in ${skillPath}, truncating`);
1970
2040
  descriptionStr = descriptionStr.slice(0, MAX_SKILL_DESCRIPTION_LENGTH);
1971
2041
  }
1972
- const allowedToolsStr = frontmatterData["allowed-tools"];
1973
- const allowedTools = allowedToolsStr ? allowedToolsStr.split(" ") : [];
2042
+ const rawTools = frontmatterData["allowed-tools"];
2043
+ let allowedTools;
2044
+ if (rawTools) if (Array.isArray(rawTools)) allowedTools = rawTools.map((t) => String(t).trim()).filter(Boolean);
2045
+ else allowedTools = String(rawTools).split(/\s+/).filter(Boolean);
2046
+ else allowedTools = [];
2047
+ let compatibilityStr = String(frontmatterData.compatibility ?? "").trim() || null;
2048
+ if (compatibilityStr && compatibilityStr.length > MAX_SKILL_COMPATIBILITY_LENGTH) {
2049
+ console.warn(`Compatibility exceeds ${MAX_SKILL_COMPATIBILITY_LENGTH} characters in ${skillPath}, truncating`);
2050
+ compatibilityStr = compatibilityStr.slice(0, MAX_SKILL_COMPATIBILITY_LENGTH);
2051
+ }
1974
2052
  return {
1975
- name: String(name),
2053
+ name,
1976
2054
  description: descriptionStr,
1977
2055
  path: skillPath,
1978
- metadata: frontmatterData.metadata || {},
1979
- license: typeof frontmatterData.license === "string" ? frontmatterData.license.trim() || null : null,
1980
- compatibility: typeof frontmatterData.compatibility === "string" ? frontmatterData.compatibility.trim() || null : null,
2056
+ metadata: validateMetadata(frontmatterData.metadata ?? {}, skillPath),
2057
+ license: String(frontmatterData.license ?? "").trim() || null,
2058
+ compatibility: compatibilityStr,
1981
2059
  allowedTools
1982
2060
  };
1983
2061
  }
@@ -2041,7 +2119,10 @@ function formatSkillsList(skills, sources) {
2041
2119
  if (skills.length === 0) return `(No skills available yet. You can create skills in ${sources.map((s) => `\`${s}\``).join(" or ")})`;
2042
2120
  const lines = [];
2043
2121
  for (const skill of skills) {
2044
- lines.push(`- **${skill.name}**: ${skill.description}`);
2122
+ const annotations = formatSkillAnnotations(skill);
2123
+ let descLine = `- **${skill.name}**: ${skill.description}`;
2124
+ if (annotations) descLine += ` (${annotations})`;
2125
+ lines.push(descLine);
2045
2126
  if (skill.allowedTools && skill.allowedTools.length > 0) lines.push(` → Allowed tools: ${skill.allowedTools.join(", ")}`);
2046
2127
  lines.push(` → Read \`${skill.path}\` for full instructions`);
2047
2128
  }
@@ -2154,9 +2235,25 @@ function createSkillsMiddleware(options) {
2154
2235
  * from `langchain` directly.
2155
2236
  */
2156
2237
  /**
2238
+ * Zod schema for a summarization event that tracks what was summarized and
2239
+ * where the cutoff is.
2240
+ *
2241
+ * Instead of rewriting LangGraph state with `RemoveMessage(REMOVE_ALL_MESSAGES)`,
2242
+ * the middleware stores this event and uses it to reconstruct the effective message
2243
+ * list on subsequent calls.
2244
+ */
2245
+ const SummarizationEventSchema = z$1.object({
2246
+ cutoffIndex: z$1.number(),
2247
+ summaryMessage: z$1.instanceof(HumanMessage),
2248
+ filePath: z$1.string().nullable()
2249
+ });
2250
+ /**
2157
2251
  * State schema for summarization middleware.
2158
2252
  */
2159
- const SummarizationStateSchema = z$1.object({ _summarizationSessionId: z$1.string().optional() });
2253
+ const SummarizationStateSchema = z$1.object({
2254
+ _summarizationSessionId: z$1.string().optional(),
2255
+ _summarizationEvent: SummarizationEventSchema.optional()
2256
+ });
2160
2257
 
2161
2258
  //#endregion
2162
2259
  //#region src/backends/store.ts