deepagents 1.13.2 → 1.13.3

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.js CHANGED
@@ -1,3 +1,3 @@
1
- import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, H as applyGrepMaxCount, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, N as SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, O as filesValue, P as createSubAgent, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, Z as normalizeReadPagination, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-BBV5JlNW.js";
2
- import { a as createAgentMemoryMiddleware, i as parseSkillMetadata, n as FilesystemBackend, o as createSettings, r as listSkills, s as findProjectRoot, t as LocalShellBackend } from "./src-CKk0apeE.js";
1
+ import { A as DEFAULT_GENERAL_PURPOSE_DESCRIPTION, B as StateBackend, C as MAX_SKILL_DESCRIPTION_LENGTH, D as createMemoryMiddleware, E as createSkillsMiddleware, F as createSubAgentMiddleware, G as resolveBackend, H as applyGrepMaxCount, I as computeSummarizationDefaults, K as adaptBackendProtocol, L as createSummarizationMiddleware, M as GENERAL_PURPOSE_SUBAGENT, N as SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, O as filesValue, P as createSubAgent, R as createFilesystemMiddleware, S as createCompletionCallbackMiddleware, T as MAX_SKILL_NAME_LENGTH, U as isSandboxBackend, V as SandboxError, W as isSandboxProtocol, Z as normalizeReadPagination, _ as createHarnessProfile, a as ASYNC_TASK_SYSTEM_PROMPT, b as createAsyncSubAgentMiddleware, c as TASK_SYSTEM_PROMPT, d as registerHarnessProfile, f as generalPurposeSubagentConfigSchema, g as EMPTY_HARNESS_PROFILE, h as serializeProfile, i as StoreBackend, j as DEFAULT_SUBAGENT_PROMPT, k as createPatchToolCallsMiddleware, l as createDeepAgent, m as parseHarnessProfileConfig, n as BaseSandbox, o as BASE_AGENT_PROMPT, p as harnessProfileConfigSchema, q as adaptSandboxProtocol, r as ContextHubBackend, s as EXECUTION_SYSTEM_PROMPT, t as LangSmithSandbox, u as getHarnessProfile, v as REQUIRED_MIDDLEWARE_NAMES, w as MAX_SKILL_FILE_SIZE, x as isAsyncSubAgent, y as ConfigurationError, z as CompositeBackend } from "./langsmith-BYWZnEVh.js";
2
+ import { a as createAgentMemoryMiddleware, i as parseSkillMetadata, n as FilesystemBackend, o as createSettings, r as listSkills, s as findProjectRoot, t as LocalShellBackend } from "./src-Blh1ZEYd.js";
3
3
  export { ASYNC_TASK_SYSTEM_PROMPT, BASE_AGENT_PROMPT, BaseSandbox, CompositeBackend, ConfigurationError, ContextHubBackend, DEFAULT_GENERAL_PURPOSE_DESCRIPTION, DEFAULT_SUBAGENT_PROMPT, EMPTY_HARNESS_PROFILE, EXECUTION_SYSTEM_PROMPT, FilesystemBackend, GENERAL_PURPOSE_SUBAGENT, LangSmithSandbox, LocalShellBackend, MAX_SKILL_DESCRIPTION_LENGTH, MAX_SKILL_FILE_SIZE, MAX_SKILL_NAME_LENGTH, REQUIRED_MIDDLEWARE_NAMES, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY, SandboxError, StateBackend, StoreBackend, TASK_SYSTEM_PROMPT, adaptBackendProtocol, adaptSandboxProtocol, applyGrepMaxCount, computeSummarizationDefaults, createAgentMemoryMiddleware, createAsyncSubAgentMiddleware, createCompletionCallbackMiddleware, createDeepAgent, createFilesystemMiddleware, createHarnessProfile, createMemoryMiddleware, createPatchToolCallsMiddleware, createSettings, createSkillsMiddleware, createSubAgent, createSubAgentMiddleware, createSummarizationMiddleware, filesValue, findProjectRoot, generalPurposeSubagentConfigSchema, getHarnessProfile, harnessProfileConfigSchema, isAsyncSubAgent, isSandboxBackend, isSandboxProtocol, listSkills, normalizeReadPagination, parseHarnessProfileConfig, parseSkillMetadata, registerHarnessProfile, resolveBackend, serializeProfile };
@@ -2,7 +2,7 @@ import { AIMessage, HumanMessage, SystemMessage, ToolMessage, anthropicPromptCac
2
2
  import { Command, REMOVE_ALL_MESSAGES, ReducedValue, StateSchema, getConfig, getCurrentTaskInput, getStore, isCommand } from "@langchain/langgraph";
3
3
  import { z } from "zod/v4";
4
4
  import micromatch from "micromatch";
5
- import { AIMessage as AIMessage$1, HumanMessage as HumanMessage$1, RemoveMessage, ToolMessage as ToolMessage$1, getBufferString } from "@langchain/core/messages";
5
+ import { AIMessage as AIMessage$1, HumanMessage as HumanMessage$1, RemoveMessage, SystemMessage as SystemMessage$1, ToolMessage as ToolMessage$1, getBufferString } from "@langchain/core/messages";
6
6
  import * as z$2 from "zod";
7
7
  import { z as z$1 } from "zod";
8
8
  import { ContextOverflowError } from "@langchain/core/errors";
@@ -3358,6 +3358,83 @@ function createSummarizationMiddleware(options) {
3358
3358
  });
3359
3359
  }
3360
3360
  //#endregion
3361
+ //#region src/middleware/utils.ts
3362
+ /**
3363
+ * Utility functions for middleware.
3364
+ *
3365
+ * This module provides shared helpers used across middleware implementations.
3366
+ */
3367
+ /**
3368
+ * Merge custom middleware into an assembled stack by `.name`.
3369
+ *
3370
+ * Matching custom middleware replaces the existing entry in place. New
3371
+ * middleware is appended after the base stack in caller-provided order.
3372
+ */
3373
+ function mergeMiddleware$1(base, custom) {
3374
+ const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
3375
+ for (const middleware of custom) merged.set(middleware.name, middleware);
3376
+ return [...merged.values()];
3377
+ }
3378
+ function middlewareNames(middleware) {
3379
+ return new Set(middleware.map((entry) => entry.name));
3380
+ }
3381
+ function matchingMiddleware(middleware, names) {
3382
+ return middleware.filter((entry) => names.has(entry.name));
3383
+ }
3384
+ /**
3385
+ * Merge custom middleware into default and tail middleware segments.
3386
+ *
3387
+ * Same-name custom entries replace matching defaults in either segment. Novel
3388
+ * custom entries are inserted between the default and tail segments unless
3389
+ * `appendNew` is false.
3390
+ */
3391
+ function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
3392
+ const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
3393
+ const tailMiddlewareNames = middlewareNames(tailMiddleware);
3394
+ const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
3395
+ const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
3396
+ return [
3397
+ ...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
3398
+ ...novelMiddleware,
3399
+ ...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
3400
+ ];
3401
+ }
3402
+ /**
3403
+ * Append text to a system message.
3404
+ *
3405
+ * Creates a new SystemMessage with the text appended to the existing content.
3406
+ * If the original message has content, the new text is separated by two newlines.
3407
+ *
3408
+ * @param systemMessage - Existing system message or null/undefined.
3409
+ * @param text - Text to add to the system message.
3410
+ * @returns New SystemMessage with the text appended.
3411
+ *
3412
+ * @example
3413
+ * ```typescript
3414
+ * const original = new SystemMessage({ content: "You are a helpful assistant." });
3415
+ * const updated = appendToSystemMessage(original, "Always be concise.");
3416
+ * // Result: SystemMessage with content "You are a helpful assistant.\n\nAlways be concise."
3417
+ * ```
3418
+ */
3419
+ function appendToSystemMessage(systemMessage, text) {
3420
+ if (!systemMessage) return new SystemMessage$1({ content: text });
3421
+ const existingContent = systemMessage.content;
3422
+ if (typeof existingContent === "string") {
3423
+ const newContent = existingContent ? `${existingContent}\n\n${text}` : text;
3424
+ return new SystemMessage$1({ content: newContent });
3425
+ }
3426
+ if (Array.isArray(existingContent)) {
3427
+ const newContent = [...existingContent];
3428
+ const textToAdd = newContent.length > 0 ? `\n\n${text}` : text;
3429
+ newContent.push({
3430
+ type: "text",
3431
+ text: textToAdd
3432
+ });
3433
+ return new SystemMessage$1({ content: newContent });
3434
+ }
3435
+ return new SystemMessage$1({ content: text });
3436
+ }
3437
+ //#endregion
3361
3438
  //#region src/middleware/subagents.ts
3362
3439
  /**
3363
3440
  * Config key used by task-tool callers to request dynamic response format.
@@ -3371,6 +3448,8 @@ const SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY = "__deepagents_subagent_response_form
3371
3448
  * Provides a minimal base prompt that can be extended by specific subagent configurations.
3372
3449
  */
3373
3450
  const DEFAULT_SUBAGENT_PROMPT = "In order to complete the objective that the user asks of you, you have access to a number of standard tools.";
3451
+ const FORKED_CONTEXT_KEY = "_deepagentsForkedContext";
3452
+ const FORK_RECURSION_REFUSAL = "You are a subagent and cannot delegate to another subagent. Complete this task yourself instead of calling this tool again.";
3374
3453
  /**
3375
3454
  * State keys excluded when passing state to subagents and when returning
3376
3455
  * updates from subagents. Summarization keys are excluded because their
@@ -3383,6 +3462,18 @@ const EXCLUDED_STATE_KEYS = [
3383
3462
  "skillsMetadata",
3384
3463
  "memoryContents",
3385
3464
  "_summarizationEvent",
3465
+ "_summarizationSessionId",
3466
+ FORKED_CONTEXT_KEY
3467
+ ];
3468
+ /**
3469
+ * State keys excluded when inheriting state into a declarative fork.
3470
+ * Narrower than `EXCLUDED_STATE_KEYS`: a fork's mirrored middleware needs
3471
+ * the parent's private channels (skills metadata, memory contents, etc.)
3472
+ * to rebuild an equivalent prompt.
3473
+ */
3474
+ const FORK_EXCLUDED_STATE_KEYS = [
3475
+ "structuredResponse",
3476
+ "_summarizationEvent",
3386
3477
  "_summarizationSessionId"
3387
3478
  ];
3388
3479
  /**
@@ -3392,25 +3483,37 @@ const EXCLUDED_STATE_KEYS = [
3392
3483
  const DEFAULT_GENERAL_PURPOSE_DESCRIPTION = "General-purpose agent for researching complex questions, searching for files and content, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries use this agent to perform the search for you. This agent has access to all tools as the main agent.";
3393
3484
  function getTaskToolDescription(subagentDescriptions) {
3394
3485
  return context`
3395
- Launch an ephemeral subagent to handle a complex, multi-step task in an isolated context window.
3486
+ Launch an ephemeral subagent to handle a complex, multi-step task.
3396
3487
 
3397
3488
  Available agent types and the tools they have access to:
3398
3489
  ${subagentDescriptions.join("\n")}
3399
3490
 
3400
3491
  Specify subagent_type to select the agent. Usage notes:
3401
3492
  - Launch multiple agents concurrently when their tasks are independent, using a single message with multiple tool calls.
3402
- - Each invocation is stateless: the agent sees only the prompt you give it and returns a single final report. Put full detail in the prompt and state exactly what it should return.
3493
+ - Each invocation is stateless by default: the agent sees only the prompt you give it and returns a single final report. Put full detail in the prompt and state exactly what it should return — unless an agent type below says it inherits your conversation instead.
3403
3494
  - The agent's report is not shown to the user; relay a summary yourself.
3404
- - Tell the agent whether to create content, analyze, or only research, since it cannot see the user's intent.
3495
+ - Tell the agent whether to create content, analyze, or only research, since it can't necessarily see the user's intent unless it inherits your conversation, as noted per agent type below.
3405
3496
  - If an agent's description says to use it proactively, do so without waiting to be asked.
3406
3497
  - When only general-purpose is available, use it for any complex, context-heavy task; it has the same capabilities as the main agent.
3407
3498
  `;
3408
3499
  }
3500
+ const FORKED_SUBAGENT_TOOL_NOTE = " (inherits your full conversation and system prompt — no need to restate context here)";
3501
+ const COMPILED_FORKED_SUBAGENT_TOOL_NOTE = " (inherits your conversation history — its system prompt is fixed in its own runnable)";
3502
+ /** Render one subagent's listing line for the task tool description. */
3503
+ function describeSubagentForTool(name, description, forked, compiled = false) {
3504
+ return `- ${name}: ${description}${forked ? compiled ? COMPILED_FORKED_SUBAGENT_TOOL_NOTE : FORKED_SUBAGENT_TOOL_NOTE : ""}`;
3505
+ }
3506
+ const FORK_TASK_PREAMBLE = "[The messages above are a prior conversation you are continuing as the subagent that was just invoked. Any mention in them of delegating to a subagent already happened — you are that subagent, not the one being asked to delegate further. If you try to delegate to another subagent yourself, it will be refused — complete this task directly. Use the specific facts, figures, and identifiers already established in that conversation when completing the task below — do not answer generically when exact details are already available above. Your actual task is below.]\n\n";
3507
+ /**
3508
+ * Whether a declarative subagent spec has `mode: "fork"` set.
3509
+ *
3510
+ * A plain boolean, not a type predicate: `SubAgent` covers both `"fork"` and
3511
+ * `"isolated"`, so there's no distinct type left to narrow to.
3512
+ */
3409
3513
  function isForkedSubAgent(value) {
3410
3514
  if (typeof value !== "object" || value == null) return false;
3411
3515
  if (!("mode" in value)) return false;
3412
- if (value.mode !== "fork") return false;
3413
- return true;
3516
+ return value.mode === "fork";
3414
3517
  }
3415
3518
  /**
3416
3519
  * Base specification for the general-purpose subagent.
@@ -3453,15 +3556,26 @@ const GENERAL_PURPOSE_SUBAGENT = {
3453
3556
  name: "general-purpose",
3454
3557
  description: DEFAULT_GENERAL_PURPOSE_DESCRIPTION,
3455
3558
  systemPrompt: DEFAULT_SUBAGENT_PROMPT,
3456
- mode: "handoff"
3559
+ mode: "isolated"
3457
3560
  };
3561
+ function filterState(state, excludedKeys) {
3562
+ const filtered = {};
3563
+ for (const [key, value] of Object.entries(state)) if (!excludedKeys.includes(key)) filtered[key] = value;
3564
+ return filtered;
3565
+ }
3458
3566
  /**
3459
3567
  * Filter state to exclude certain keys when passing to subagents
3460
3568
  */
3461
3569
  function filterStateForSubagent(state) {
3462
- const filtered = {};
3463
- for (const [key, value] of Object.entries(state)) if (!EXCLUDED_STATE_KEYS.includes(key)) filtered[key] = value;
3464
- return filtered;
3570
+ return filterState(state, EXCLUDED_STATE_KEYS);
3571
+ }
3572
+ /**
3573
+ * Filter state to exclude only the keys a declarative fork must not resume
3574
+ * (structured response, summarization event/session) — see
3575
+ * `FORK_EXCLUDED_STATE_KEYS`.
3576
+ */
3577
+ function filterStateForFork(state) {
3578
+ return filterState(state, FORK_EXCLUDED_STATE_KEYS);
3465
3579
  }
3466
3580
  /**
3467
3581
  * Invalid tool message block types
@@ -3505,6 +3619,15 @@ function stripInFlightAIMessage(messages) {
3505
3619
  const last = messages.at(-1);
3506
3620
  return AIMessage$1.isInstance(last) && (last.tool_calls?.length ?? 0) > 0 ? messages.slice(0, -1) : messages;
3507
3621
  }
3622
+ const ForkedContextStateSchema = z.object({ [FORKED_CONTEXT_KEY]: z.boolean().optional() });
3623
+ function createForkTaskToolMiddleware(taskTool) {
3624
+ return createMiddleware({
3625
+ name: "forkTaskToolMiddleware",
3626
+ stateSchema: ForkedContextStateSchema,
3627
+ tools: [taskTool],
3628
+ beforeAgent: () => ({ [FORKED_CONTEXT_KEY]: true })
3629
+ });
3630
+ }
3508
3631
  /**
3509
3632
  * Create a runnable agent from a declarative `SubAgent` spec.
3510
3633
  *
@@ -3534,6 +3657,17 @@ function createSubAgent(spec, options) {
3534
3657
  });
3535
3658
  }
3536
3659
  /**
3660
+ * Resolve a fork's system prompt: the parent's inherited prompt, with the
3661
+ * fork's own systemPrompt (if any) appended as an addendum rather than
3662
+ * replacing it.
3663
+ */
3664
+ function resolveForkSystemPrompt(parentSystemPrompt, forkAddendum) {
3665
+ if (!forkAddendum) return parentSystemPrompt ?? "";
3666
+ const addendumText = typeof forkAddendum === "string" ? forkAddendum : forkAddendum.text;
3667
+ if (SystemMessage.isInstance(parentSystemPrompt)) return appendToSystemMessage(parentSystemPrompt, addendumText);
3668
+ return parentSystemPrompt ? `${parentSystemPrompt}\n\n${addendumText}` : addendumText;
3669
+ }
3670
+ /**
3537
3671
  * Create subagent instances from specifications.
3538
3672
  *
3539
3673
  * Returns compiled agents, raw specs keyed by name (for on-demand
@@ -3541,13 +3675,18 @@ function createSubAgent(spec, options) {
3541
3675
  * of names that should fork the parent's conversation.
3542
3676
  */
3543
3677
  function getSubagents(options) {
3544
- const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, parentSystemPrompt = null } = options;
3678
+ const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware: gpMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, parentSystemPrompt = null, mirroredTaskTool } = options;
3545
3679
  const defaultSubagentMiddleware = defaultMiddleware || [];
3546
3680
  const generalPurposeMiddlewareBase = gpMiddleware || defaultSubagentMiddleware;
3547
3681
  const agents = {};
3548
3682
  const specsByName = {};
3549
3683
  const subagentDescriptions = [];
3550
3684
  const forkModeNames = /* @__PURE__ */ new Set();
3685
+ const seenNames = new Set(generalPurposeAgent ? ["general-purpose"] : []);
3686
+ for (const agentParams of subagents) {
3687
+ if (seenNames.has(agentParams.name)) throw new Error(`Duplicate subagent name '${agentParams.name}'; each subagent must have a unique name.`);
3688
+ seenNames.add(agentParams.name);
3689
+ }
3551
3690
  if (generalPurposeAgent) {
3552
3691
  const generalPurposeMiddleware = [...generalPurposeMiddlewareBase];
3553
3692
  if (defaultInterruptOn) generalPurposeMiddleware.push(humanInTheLoopMiddleware({ interruptOn: defaultInterruptOn }));
@@ -3561,24 +3700,34 @@ function getSubagents(options) {
3561
3700
  };
3562
3701
  agents["general-purpose"] = createSubAgent(gpSpec);
3563
3702
  specsByName["general-purpose"] = gpSpec;
3564
- subagentDescriptions.push(`- general-purpose: ${DEFAULT_GENERAL_PURPOSE_DESCRIPTION}`);
3703
+ subagentDescriptions.push(describeSubagentForTool("general-purpose", DEFAULT_GENERAL_PURPOSE_DESCRIPTION, false));
3565
3704
  }
3566
3705
  for (const agentParams of subagents) {
3567
3706
  const rawMode = agentParams.mode;
3568
- if (rawMode != null && rawMode !== "handoff" && rawMode !== "fork") throw new Error(`SubAgent '${agentParams.name}' has invalid mode '${rawMode}' — must be "handoff" or "fork".`);
3569
- subagentDescriptions.push(`- ${agentParams.name}: ${agentParams.description}`);
3707
+ if (rawMode != null && rawMode !== "isolated" && rawMode !== "fork" && rawMode !== "handoff") throw new Error(`SubAgent '${agentParams.name}' has invalid mode '${rawMode}' — must be "isolated" or "fork".`);
3708
+ const forked = isForkedSubAgent(agentParams);
3709
+ const compiled = "runnable" in agentParams;
3710
+ subagentDescriptions.push(describeSubagentForTool(agentParams.name, agentParams.description, forked, compiled));
3570
3711
  if ("runnable" in agentParams) {
3571
3712
  agents[agentParams.name] = agentParams.runnable;
3572
3713
  specsByName[agentParams.name] = agentParams;
3573
- if (isForkedSubAgent(agentParams)) forkModeNames.add(agentParams.name);
3574
- } else if (isForkedSubAgent(agentParams)) {
3714
+ if (forked) forkModeNames.add(agentParams.name);
3715
+ continue;
3716
+ }
3717
+ const subagentMiddleware = [...defaultSubagentMiddleware, ...agentParams.middleware ?? []];
3718
+ if (forked) {
3719
+ const rawSkills = agentParams.skills;
3720
+ if (Array.isArray(rawSkills) && rawSkills.length > 0) throw new Error(`SubAgent '${agentParams.name}' cannot set skills under mode: "fork"; the parent's skills are inherited instead.`);
3721
+ const resolvedSystemPrompt = resolveForkSystemPrompt(parentSystemPrompt, agentParams.systemPrompt);
3722
+ const fsIndex = subagentMiddleware.findIndex((m) => m.name === "FilesystemMiddleware");
3723
+ subagentMiddleware.splice(fsIndex + 1, 0, createForkTaskToolMiddleware(mirroredTaskTool));
3575
3724
  const resolvedSpec = {
3576
3725
  ...agentParams,
3577
- systemPrompt: parentSystemPrompt ?? "",
3726
+ systemPrompt: resolvedSystemPrompt,
3578
3727
  mode: void 0,
3579
3728
  model: agentParams.model ?? defaultModel,
3580
3729
  tools: agentParams.tools ?? defaultTools,
3581
- middleware: [...defaultSubagentMiddleware, ...agentParams.middleware ?? []],
3730
+ middleware: subagentMiddleware,
3582
3731
  interruptOn: agentParams.interruptOn ?? defaultInterruptOn ?? void 0
3583
3732
  };
3584
3733
  agents[agentParams.name] = createSubAgent(resolvedSpec);
@@ -3587,10 +3736,10 @@ function getSubagents(options) {
3587
3736
  } else {
3588
3737
  const resolvedSpec = {
3589
3738
  ...agentParams,
3590
- mode: "handoff",
3739
+ mode: "isolated",
3591
3740
  model: agentParams.model ?? defaultModel,
3592
3741
  tools: agentParams.tools ?? defaultTools,
3593
- middleware: [...defaultSubagentMiddleware, ...agentParams.middleware ?? []],
3742
+ middleware: subagentMiddleware,
3594
3743
  interruptOn: agentParams.interruptOn ?? defaultInterruptOn ?? void 0
3595
3744
  };
3596
3745
  agents[agentParams.name] = createSubAgent(resolvedSpec);
@@ -3609,16 +3758,12 @@ function getSubagents(options) {
3609
3758
  */
3610
3759
  function createTaskTool(options) {
3611
3760
  const { defaultModel, defaultTools, defaultMiddleware, generalPurposeMiddleware, defaultInterruptOn, subagents, generalPurposeAgent, taskDescription, parentSystemPrompt = null } = options;
3612
- const { agents: subagentGraphs, specsByName, descriptions: subagentDescriptions, forkModeNames } = getSubagents({
3613
- defaultModel,
3614
- defaultTools,
3615
- defaultMiddleware,
3616
- generalPurposeMiddleware,
3617
- defaultInterruptOn,
3618
- subagents,
3619
- generalPurposeAgent,
3620
- parentSystemPrompt
3621
- });
3761
+ const subagentNames = [...generalPurposeAgent ? ["general-purpose"] : [], ...subagents.map((spec) => spec.name)];
3762
+ const subagentDescriptions = [...generalPurposeAgent ? [describeSubagentForTool("general-purpose", DEFAULT_GENERAL_PURPOSE_DESCRIPTION, false)] : [], ...subagents.map((spec) => describeSubagentForTool(spec.name, spec.description, isForkedSubAgent(spec), "runnable" in spec))];
3763
+ const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
3764
+ let subagentGraphs = {};
3765
+ let specsByName = {};
3766
+ let forkModeNames = /* @__PURE__ */ new Set();
3622
3767
  function selectSubagent(subagentType, config) {
3623
3768
  const spec = specsByName[subagentType];
3624
3769
  const responseFormat = config.configurable?.[SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY];
@@ -3626,18 +3771,19 @@ function createTaskTool(options) {
3626
3771
  if ("runnable" in spec || responseFormat == null) return subagentGraphs[subagentType];
3627
3772
  return createSubAgent(spec, { responseFormat });
3628
3773
  }
3629
- const finalTaskDescription = taskDescription ? taskDescription : getTaskToolDescription(subagentDescriptions);
3630
- return tool(async (input, config) => {
3774
+ async function runTask(input, config) {
3631
3775
  const { description, subagent_type } = input;
3776
+ const currentState = getCurrentTaskInput();
3777
+ if (currentState[FORKED_CONTEXT_KEY]) return FORK_RECURSION_REFUSAL;
3632
3778
  if (!(subagent_type in subagentGraphs)) {
3633
3779
  const allowedTypes = Object.keys(subagentGraphs).map((k) => `\`${k}\``).join(", ");
3634
3780
  throw new Error(`Error: invoked agent of type ${subagent_type}, the only allowed types are ${allowedTypes}`);
3635
3781
  }
3636
3782
  const shouldFork = forkModeNames.has(subagent_type);
3637
3783
  const subagent = selectSubagent(subagent_type, config);
3638
- const currentState = getCurrentTaskInput();
3639
- const subagentState = filterStateForSubagent(currentState);
3640
- if (shouldFork) subagentState.messages = [...getEffectiveMessages(stripInFlightAIMessage(currentState.messages ?? []), currentState), new HumanMessage$1({ content: description })];
3784
+ const spec = specsByName[subagent_type];
3785
+ const subagentState = shouldFork && !("runnable" in spec) ? filterStateForFork(currentState) : filterStateForSubagent(currentState);
3786
+ if (shouldFork) subagentState.messages = [...getEffectiveMessages(stripInFlightAIMessage(currentState.messages ?? []), currentState), new HumanMessage$1({ content: FORK_TASK_PREAMBLE + description })];
3641
3787
  else subagentState.messages = [new HumanMessage$1({ content: description })];
3642
3788
  subagentState._summarizationSessionId = `session_${crypto.randomUUID().substring(0, 8)}`;
3643
3789
  const subagentConfig = {
@@ -3664,14 +3810,35 @@ function createTaskTool(options) {
3664
3810
  return content;
3665
3811
  }
3666
3812
  return returnCommandWithStateUpdate(result, config.toolCall.id);
3667
- }, {
3813
+ }
3814
+ const taskToolSchema = z.object({
3815
+ description: z.string().describe("The task to execute with the selected agent"),
3816
+ subagent_type: z.string().describe(`Name of the agent to use. Available: ${subagentNames.join(", ")}`)
3817
+ });
3818
+ const taskTool = tool(runTask, {
3668
3819
  name: "task",
3669
3820
  description: finalTaskDescription,
3670
- schema: z.object({
3671
- description: z.string().describe("The task to execute with the selected agent"),
3672
- subagent_type: z.string().describe(`Name of the agent to use. Available: ${Object.keys(subagentGraphs).join(", ")}`)
3821
+ schema: taskToolSchema
3822
+ });
3823
+ const { agents, specsByName: resolvedSpecsByName, forkModeNames: resolvedForkModeNames } = getSubagents({
3824
+ defaultModel,
3825
+ defaultTools,
3826
+ defaultMiddleware,
3827
+ generalPurposeMiddleware,
3828
+ defaultInterruptOn,
3829
+ subagents,
3830
+ generalPurposeAgent,
3831
+ parentSystemPrompt,
3832
+ mirroredTaskTool: tool(runTask, {
3833
+ name: "task",
3834
+ description: finalTaskDescription,
3835
+ schema: taskToolSchema
3673
3836
  })
3674
3837
  });
3838
+ subagentGraphs = agents;
3839
+ specsByName = resolvedSpecsByName;
3840
+ forkModeNames = resolvedForkModeNames;
3841
+ return taskTool;
3675
3842
  }
3676
3843
  /**
3677
3844
  * Create subagent middleware with task tool
@@ -4673,43 +4840,6 @@ function createSkillsMiddleware(options) {
4673
4840
  });
4674
4841
  }
4675
4842
  //#endregion
4676
- //#region src/middleware/utils.ts
4677
- /**
4678
- * Merge custom middleware into an assembled stack by `.name`.
4679
- *
4680
- * Matching custom middleware replaces the existing entry in place. New
4681
- * middleware is appended after the base stack in caller-provided order.
4682
- */
4683
- function mergeMiddleware$1(base, custom) {
4684
- const merged = new Map(base.map((middleware) => [middleware.name, middleware]));
4685
- for (const middleware of custom) merged.set(middleware.name, middleware);
4686
- return [...merged.values()];
4687
- }
4688
- function middlewareNames(middleware) {
4689
- return new Set(middleware.map((entry) => entry.name));
4690
- }
4691
- function matchingMiddleware(middleware, names) {
4692
- return middleware.filter((entry) => names.has(entry.name));
4693
- }
4694
- /**
4695
- * Merge custom middleware into default and tail middleware segments.
4696
- *
4697
- * Same-name custom entries replace matching defaults in either segment. Novel
4698
- * custom entries are inserted between the default and tail segments unless
4699
- * `appendNew` is false.
4700
- */
4701
- function mergeMiddlewareStack(defaultMiddleware, customMiddleware, tailMiddleware = [], options = {}) {
4702
- const defaultMiddlewareNames = middlewareNames(defaultMiddleware);
4703
- const tailMiddlewareNames = middlewareNames(tailMiddleware);
4704
- const knownMiddlewareNames = /* @__PURE__ */ new Set([...defaultMiddlewareNames, ...tailMiddlewareNames]);
4705
- const novelMiddleware = options.appendNew === false ? [] : customMiddleware.filter((entry) => !knownMiddlewareNames.has(entry.name));
4706
- return [
4707
- ...mergeMiddleware$1(defaultMiddleware, matchingMiddleware(customMiddleware, defaultMiddlewareNames)),
4708
- ...novelMiddleware,
4709
- ...mergeMiddleware$1(tailMiddleware, matchingMiddleware(customMiddleware, tailMiddlewareNames))
4710
- ];
4711
- }
4712
- //#endregion
4713
4843
  //#region src/middleware/completion_callback.ts
4714
4844
  /**
4715
4845
  * Callback middleware for async subagents.
@@ -6338,8 +6468,18 @@ function createDeepAgent(params = {}) {
6338
6468
  providerHint: getModelProvider(model),
6339
6469
  identifierHint: getModelIdentifier(model)
6340
6470
  });
6341
- const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !harnessProfile.excludedTools.has(toolName));
6342
- const profileFilesystemTools = filesystemTools.length === FILESYSTEM_TOOL_NAMES.length ? void 0 : filesystemTools.includes("read_file") ? filesystemTools : ["read_file", ...filesystemTools];
6471
+ const computeProfileFilesystemTools = (profile) => {
6472
+ const filesystemTools = FILESYSTEM_TOOL_NAMES.filter((toolName) => !profile.excludedTools.has(toolName));
6473
+ return filesystemTools.length === FILESYSTEM_TOOL_NAMES.length ? void 0 : filesystemTools.includes("read_file") ? filesystemTools : ["read_file", ...filesystemTools];
6474
+ };
6475
+ const profileFilesystemTools = computeProfileFilesystemTools(harnessProfile);
6476
+ const resolveSubagentProfile = (subagentModel) => {
6477
+ if (subagentModel == null || subagentModel === model) return harnessProfile;
6478
+ return typeof subagentModel === "string" ? resolveHarnessProfile({ spec: subagentModel }) : resolveHarnessProfile({
6479
+ providerHint: getModelProvider(subagentModel),
6480
+ identifierHint: getModelIdentifier(subagentModel)
6481
+ });
6482
+ };
6343
6483
  const toolOverrides = harnessProfile.toolDescriptionOverrides;
6344
6484
  const effectiveTools = Object.keys(toolOverrides).length > 0 ? tools.map((t) => t.name in toolOverrides ? Object.assign(Object.create(Object.getPrototypeOf(t)), t, { description: toolOverrides[t.name] }) : t) : tools;
6345
6485
  const anthropicModel = isAnthropicModel(model);
@@ -6375,44 +6515,50 @@ function createDeepAgent(params = {}) {
6375
6515
  * Only the general-purpose subagent inherits the main agent's skills.
6376
6516
  * If a custom subagent needs skills, it must specify its own `skills` array.
6377
6517
  */
6378
- const createSubagentDefaultMiddleware = (input) => {
6518
+ const createSubagentDefaultMiddleware = (input, subagentProfile, forked) => {
6379
6519
  const effectivePermissions = input.permissions ?? permissions;
6380
6520
  return [
6381
6521
  createFilesystemMiddleware({
6382
6522
  backend,
6383
6523
  permissions: effectivePermissions,
6384
- tools: profileFilesystemTools
6524
+ tools: computeProfileFilesystemTools(subagentProfile)
6385
6525
  }),
6386
6526
  createSummarizationMiddleware({ backend }),
6387
6527
  createPatchToolCallsMiddleware(),
6388
- ...input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
6528
+ ...!forked && input.skills != null && input.skills.length > 0 ? [createSkillsMiddleware({
6389
6529
  backend,
6390
6530
  sources: input.skills
6391
6531
  })] : []
6392
6532
  ];
6393
6533
  };
6394
- const buildSubagentMiddleware = (input, isForkable) => {
6395
- let subagentMiddleware = mergeMiddlewareStack(createSubagentDefaultMiddleware(input), input.middleware ?? [], [
6396
- ...resolveMiddleware(harnessProfile.extraMiddleware),
6534
+ const buildSubagentMiddleware = (input) => {
6535
+ const subagentProfile = resolveSubagentProfile(input.model);
6536
+ const forked = isForkedSubAgent(input);
6537
+ const subagentDefaultMiddleware = createSubagentDefaultMiddleware(input, subagentProfile, forked);
6538
+ if (forked && skills != null && skills.length > 0) subagentDefaultMiddleware.unshift(createSkillsMiddleware({
6539
+ backend,
6540
+ sources: skills
6541
+ }));
6542
+ let subagentMiddleware = mergeMiddlewareStack(subagentDefaultMiddleware, forked && customMiddleware.length > 0 ? mergeMiddleware$1(customMiddleware, input.middleware ?? []) : input.middleware ?? [], [
6543
+ ...resolveMiddleware(subagentProfile.extraMiddleware),
6397
6544
  ...cacheMiddleware,
6398
- ...isForkable ? memoryMiddleware : []
6545
+ ...forked && memory != null && memory.length > 0 ? [createMemoryMiddleware({
6546
+ backend,
6547
+ sources: memory,
6548
+ addCacheControl: anthropicModel
6549
+ })] : []
6399
6550
  ]);
6400
- if (harnessProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !harnessProfile.excludedMiddleware.has(middleware.name));
6551
+ if (subagentProfile.excludedMiddleware.size > 0) subagentMiddleware = subagentMiddleware.filter((middleware) => !subagentProfile.excludedMiddleware.has(middleware.name));
6552
+ if (subagentProfile.excludedTools.size > 0) subagentMiddleware.push(createToolExclusionMiddleware(subagentProfile.excludedTools));
6401
6553
  return subagentMiddleware;
6402
6554
  };
6403
6555
  const normalizeSubagentSpec = (input) => ({
6404
6556
  ...input,
6405
- tools: input.tools ?? [],
6406
- middleware: buildSubagentMiddleware(input, false)
6407
- });
6408
- const normalizeForkedSubagentSpec = (input) => ({
6409
- ...input,
6410
- tools: input.tools ?? [],
6411
- middleware: buildSubagentMiddleware(input, true)
6557
+ middleware: buildSubagentMiddleware(input)
6412
6558
  });
6413
6559
  const allSubagents = subagents;
6414
6560
  const asyncSubAgents = allSubagents.filter((item) => isAsyncSubAgent(item));
6415
- const inlineSubagents = allSubagents.filter((item) => !isAsyncSubAgent(item)).map((item) => "runnable" in item ? item : isForkedSubAgent(item) ? normalizeForkedSubagentSpec(item) : normalizeSubagentSpec(item));
6561
+ const inlineSubagents = allSubagents.filter((item) => !isAsyncSubAgent(item)).map((item) => "runnable" in item ? item : normalizeSubagentSpec(item));
6416
6562
  const gpConfig = harnessProfile.generalPurposeSubagent;
6417
6563
  if (!(gpConfig?.enabled === false) && !inlineSubagents.some((item) => item.name === GENERAL_PURPOSE_SUBAGENT["name"])) {
6418
6564
  const gpSystemPrompt = gpConfig?.systemPrompt ?? applyProfilePrompt(harnessProfile, GENERAL_PURPOSE_SUBAGENT.systemPrompt);
@@ -8585,4 +8731,4 @@ var LangSmithSandbox = class LangSmithSandbox extends BaseSandbox {
8585
8731
  //#endregion
8586
8732
  export { DEFAULT_GENERAL_PURPOSE_DESCRIPTION as A, StateBackend as B, MAX_SKILL_DESCRIPTION_LENGTH as C, createMemoryMiddleware as D, createSkillsMiddleware as E, createSubAgentMiddleware as F, resolveBackend as G, applyGrepMaxCount as H, computeSummarizationDefaults as I, checkEmptyContent as J, adaptBackendProtocol as K, createSummarizationMiddleware as L, GENERAL_PURPOSE_SUBAGENT as M, SUBAGENT_RESPONSE_FORMAT_CONFIG_KEY as N, filesValue as O, createSubAgent as P, performStringReplacement as Q, createFilesystemMiddleware as R, createCompletionCallbackMiddleware as S, MAX_SKILL_NAME_LENGTH as T, isSandboxBackend as U, SandboxError as V, isSandboxProtocol as W, isTextMimeType as X, getMimeType as Y, normalizeReadPagination as Z, createHarnessProfile as _, ASYNC_TASK_SYSTEM_PROMPT as a, createAsyncSubAgentMiddleware as b, TASK_SYSTEM_PROMPT as c, registerHarnessProfile as d, generalPurposeSubagentConfigSchema as f, EMPTY_HARNESS_PROFILE as g, serializeProfile as h, StoreBackend as i, DEFAULT_SUBAGENT_PROMPT as j, createPatchToolCallsMiddleware as k, createDeepAgent as l, parseHarnessProfileConfig as m, BaseSandbox as n, BASE_AGENT_PROMPT as o, harnessProfileConfigSchema as p, adaptSandboxProtocol as q, ContextHubBackend as r, EXECUTION_SYSTEM_PROMPT as s, LangSmithSandbox as t, getHarnessProfile as u, REQUIRED_MIDDLEWARE_NAMES as v, MAX_SKILL_FILE_SIZE as w, isAsyncSubAgent as x, ConfigurationError as y, CompositeBackend as z };
8587
8733
 
8588
- //# sourceMappingURL=langsmith-BBV5JlNW.js.map
8734
+ //# sourceMappingURL=langsmith-BYWZnEVh.js.map